用自己的方法写出来了,下标很容易错。。。
其实感觉KMP算法还有改进的余地,因为 Pi[ ] 这个数组在计算的时候只会有两种情况:
1、要么碰到不等的数了,就为0
2、要么继续相等,就+1
#include <iostream> #include <string.h> using namespace std; int Pi[100]; //最终的数组 /************************************************************************/ /* athor:Bill Wang */ /************************************************************************/ //计算每个子串的最大前缀pi int count_max(char *P,int len) { int i,j; //len是串长度 for (i=len-1;i>=1;i--) { //从最乐观的开始,碰到一个可以的就返回 for (j=1;j<=i;j++) { //这里只要匹配成功就可以返回了 if (P[j] != P[len-i+j]) break; } if(j>i) //成功匹配 return i; } return 0; } void Prefix_fun(char *P) { //cout<<strlen(P)<<endl; int m=strlen(P); //P的长度,这里是10 Pi[1]=0; for(int q=2;q<=m;q++) { //已得到子串 如 abababa,计算其Pi Pi[q]=count_max(P,q); } } int main() { char P[]="zababababca"; Prefix_fun(P); for(int i=1;i<=10;i++) printf("%d ",Pi[i]); cout<<endl; while(1); return 0; }
算导自带的算法:
#include <iostream> #include <string.h> using namespace std; int Pi[100]; //最终的数组 void Prefix_fun(char *P) { //cout<<strlen(P)<<endl; int m=strlen(P); //P的长度,这里是10 Pi[1]=0; int k=0; //一个中间变量 for(int q=2;q<=m;q++) { while( k>0 && P[k+1]!=P[q]) k=Pi[k]; if (P[k+1] == P[q]) k++; Pi[q]=k; } } int main() { char P[]="zababababca"; Prefix_fun(P); for(int i=1;i<=10;i++) printf("%d ",Pi[i]); cout<<endl; while(1); return 0; }