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个元素至多有 i-2 对相等的元素 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++;}
if(i > s)
{
break;
}
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 }
只有0和1的世界是简单的