首页 > 代码库 > KMP算法

KMP算法

废话不多说,看毛片算法的核心在于next数组。

很多地方用的都是严书上的方法来求解next数组,代码确实简洁明了,但是可能对于初学者来说不容易想到,甚至不是一下子能理解。(好了,其实我说的就是自己,别笑)

以下为严师太的代码,也是很多人用的

照着代码用手调试了一遍,确实厉害

但是就跟我看别人写的递归算法时,照着推一遍,能懂,但是自己想不到,水平低,怪我。

int Next(char *p,int * next)//课本
{
    int s=0,i=1,j=0;
    char *q=p;
    while(*q!=‘\0‘)
    {
        s++;
        q++;
    }
    s--;
    next[1]=0;
    while(i<s)
    {
        if(j==0||p[i]==p[j])
        {
            i++;
            j++;
            next[i]=j;
        }
        else j=next[j];
    }
    return 0;
}

  

这里本人贴一段自己经过一晚上思考得出来的思路,也许不完善,也许别人已经有过类似更好的,但是我只是想分享给初学者一点思路,希望共同进步。

 1 int Next(char *p,int * next)//p为模式串
 2 {
 3     char *q=p;
 4     int i,j,k,l,s=0,m=1;
 5     while(*q!=\0)
 6     {
 7         s++;
 8         q++;
 9     }
10     s--;//求出模式串的长度,这里依照书上的规定从下标为1的算起
11     q=p;
12     next[0]=s;
13     next[1]=0;
14     next[2]=1;
15     for(i=3;i<=s;i++)//所需求解的next数组元素个数
16     {
17         for(l=1;l<=i-2;l++)//每次最多进行i-2回循环,因为模式串第i个元素之前一共有i-1个元素,而i-1个元素至多有三对相等的元素
18         {
19             for(j=1,k=j+l;j<=i-1-l;j++,k++)//从相等对数最多对的情况判断
20             {
21                 if(q[j]!=q[k]){ m=0; break;}//一旦出现不相等,直接跳出循环,进行下一次判断,并且把m置为0,表示这种情况不符合
22             }
23             if(m) break;//经过上面的循环,若m仍然为1,则代表符合情况,不用再判断相等对数更少的情况了,直接跳出求解下一个next数组中元素的值
24             m=1;
25         }
26         next[i]=i-l;//此处是化简后的结果,可以自己演算一下。
27     }
28     return 0;
29 }
过程如下:
技术分享

KMP完整代码如下:
 1 #include <iostream>
 2 
 3 using namespace std;
 4 #define MAX_SIZE 10
 5 
 6 
 7 int Next(char *p,int * next)
 8 {
 9     char *q=p;
10     int i,j,k,l,s=0,m=1;
11     while(*q!=\0)
12     {
13         s++;
14         q++;
15     }
16     s--;
17     q=p;
18     next[0]=s;
19     next[1]=0;
20     next[2]=1;
21     for(i=3;i<=s;i++)
22     {
23         for(l=1;l<=i-2;l++)
24         {
25             for(j=1,k=j+l;j<=i-1-l;j++,k++)
26             {
27                 if(q[j]!=q[k]){ m=0; break;}
28             }
29             if(m) break;6
30             m=1;
31         }
32         next[i]=i-l;
33     }
34     return 0;
35 }
36 
37 
38 
39 int Index(char *S,char *T)
40 {
41     int next[MAX_SIZE],i=1,j=1,s=0,t=0,pos=1;
42     char *p=S,*q=T;
43     while(*p!=\0)
44     {
45         s++;
46         p++;
47     }
48     s--;
49     while(*q!=\0)
50     {
51         t++;
52         q++;
53     }
54     t--;
55     Next(T,next);
56     while(i<=s&&j<=t)
57     {
58         if(j==0) {i++;j++;}
59         if(S[i]==T[j]){i++;j++;}
60         else j=next[j];
61     }
62     if(j>t)
63     {
64         pos=i-t;
65         cout<<"模式串在主串中第"<<pos<<"个位置匹配"<<endl;
66         return 0;
67     }
68     if(i>s&&j<=t)
69     {
70         cout<<"模式串无法与主串匹配!"<<endl;
71         return 0;
72     }
73 }
74 int main()
75 {
76     char *S1="#ababcabcacbab";
77     char *T1="#abcac";
78     char *S2="#www.FishC.com";
79     char *T2="#ww.";
80     char *S3="#bbsbbs.FishC";
81     char *T3="#bbsbbc";
82     char *S4="#00000000000000000001";
83     char *T4="#00000001";
84     Index(S1,T1);
85     Index(S2,T2);
86     Index(S3,T3);
87     Index(S4,T4);
88     return 0;
89 }

 


 

KMP算法