• 【算法与数据结构】字符串匹配之KMP算法


     

     1 // KMP.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include <iostream>
     6 #include <new>
     7 using namespace std;
     8 
     9 /************************************************************************
    10    这个算法的关键在于不用回溯指示主串当前比较位置的变量i,
    11    当主串和模式串失配时,只需要将模式串向右滑动尽可能大的距离
    12    即决定主串当前位置i上的元素 应该和 模式串的哪个元素比较
    13    即关键在于求的一个next[j]数组,当主串在i位置和模式串的j位置失配时,
    14    应该将模式串的next[j]位置元素和主串i位置元素开始比较,重复此过程
    15 
    16    所以问题的关键在于求解一个next[j]数组,这个数组的求解是和主串无关的。
    17 
    18 ************************************************************************/
    19 
    20 //以下代码并没有完全的对参数进行检查
    21 
    22 //求解next数组
    23 //lpString为模式串
    24 //next为输入数组
    25 void GetNext(const TCHAR* lpString, int* next)
    26 {
    27     if (NULL == lpString || NULL == next){ return; }
    28     int j = 0;
    29     int k = 0;
    30     next[0] = -1;
    31     j = 0;
    32     k = -1;
    33 
    34     int length = _tcslen(lpString);
    35     while (j < length - 1)
    36     {
    37         if (-1 == k || lpString[j] == lpString[k])
    38         {
    39             ++j;
    40             ++k;
    41             next[j] = k;
    42         }
    43         else
    44         {
    45             k = next[k];
    46         }        
    47     }    
    48 }
    49 
    50 
    51 int KMPMatch(const TCHAR* lpMain, const TCHAR* lpMatch)
    52 {
    53     int nMain = _tcslen(lpMain);
    54     int nMatch = _tcslen(lpMatch);
    55     int* pNext = new int[nMatch]();
    56     int i = 0;
    57     int j = 0;
    58 
    59     if (NULL == pNext)
    60     {
    61         return -1;
    62     }
    63 
    64     GetNext(lpMatch, pNext);
    65     while (i < nMain && j < nMatch)
    66     {
    67         if (-1 == j || lpMain[i] == lpMatch[j])
    68         {
    69             ++i; ++j;
    70         }
    71         else
    72         {
    73             j = pNext[j];
    74         }                
    75     }
    76 
    77     delete[] pNext;
    78     pNext = NULL;
    79 
    80     if (j >= nMatch)
    81     {
    82         return i - nMatch;
    83     }
    84 
    85     return -1;
    86 }
    87 
    88 int _tmain(int argc, _TCHAR* argv[])
    89 {
    90     const TCHAR* lpMain = _T("helloworld");
    91     const TCHAR* lpMatch = _T("oworl");
    92 
    93     wcout<<"模式串 "<<lpMatch<<" 在主串 "<<lpMain<<" 中的位置为 " 
    94         <<KMPMatch(lpMain, lpMatch)<<endl;;
    95 
    96     return 0;
    97 }

     

    执行结果如下:

     

     

  • 相关阅读:
    du命令、df命令、磁盘分区
    du命令、df命令、磁盘分区
    C#中类和结构体的区别
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    JAVA并查集
    JAVAPrim最小生成树
    自媒体创业怎么起步?如何选择自媒体平台?
    如何在互联网创业?有什么好的技巧?
  • 原文地址:https://www.cnblogs.com/cuish/p/3680420.html
Copyright © 2020-2023  润新知