一个:KMP原型
next数组表示的是,最长前缀和后缀相等的长度。
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> using namespace std; const int N=1000000; int next[N]; char s[N],t[N]; /*********KMP小结**********/ //求next数组 void getNext(int lt) { int k=-1,i=0; next[0]=-1; while(i<lt) { if(k==-1||s[k]==t[i]) next[++i]=++k; else k=next[k]; } } //KMP求模板串第一次出现的位置 int getIndex(int ls,int lt) { getNext(lt); int i=0,k=0; while(i<ls&&k<lt) { if(k==-1||s[i]==t[k]) { i++; k++; } else k=next[k]; } if(k==lt) return i-lt+1; //返回的下标从0,開始算。else return -1; } //KMP求模板串出现的次数 int getCnt(int ls,int lt) { getNext(lt); int k=0,cnt=0; for(int i=0;i<ls;i++) { while(k!=-1&&s[i]!=t[k]) k=next[k]; if(s[i]==t[k]) k++; if(k==lt){ cnt++; k=next[k]; } } return cnt; } int main() { cin>>s>>t; int ls=strlen(s); int lt=strlen(t); cout<<getIndex(ls,lt)<<endl; return 0; }
二:扩展KMP
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; /******扩展的KMP******/ const int N=100000; int next[N]; int extand[N]; char s[N],t[N]; void getNext(int lt) { next[0]=lt; int a=0; while(a<lt-1&&t[a]==t[a+1]) a++; next[1]=a; a=1; for(int k=2;k<lt;k++) { int p=a+next[a]-1; int L=next[k-a]; if(k-1+L>=p){ int j=(p-k+1)>0?(p-k+1):0; while(k+j<lt&&t[k+j]==t[j]) j++; next[k]=j; a=k; } else next[k]=L; } } void getExtand(int ls,int lt) { getNext(lt); int minLen=min(ls,lt); int a=0; while(a<minLen&&s[a]==t[a]) a++; extand[0]=a; a=0; for(int k=1;k<ls;k++) { int p=a+extand[a]-1; int L=next[k-a]; if(k-1+L>=p){ int j=(p-k+1)>0?(p-k+1):0; while(k+j<ls&&j<lt&&s[k+j]==t[j]) j++; extand[k]=j; a=k; } else extand[k]=L; } } int main() { cin>>s>>t; int ls=strlen(s); int lt=strlen(t); getExtand(ls,lt); for(int i=0;i<ls;i++) cout<<extand[i]<<endl; return 0; }
版权声明:本文博客原创文章。博客,未经同意,不得转载。