『一本通』KMP算法
#include<bits/stdc++.h> #define N 1005 using namespace std; int n,m,ans,p[N]; char a[N],b[N]; void GetP() { p[1]=0; int j=0; for(int i=2;i<=m;i++) { while(j&&b[i]!=b[j+1]) j=p[j]; if(b[i]==b[j+1]) j++; p[i]=j; } } void KMP() { int j=0; for(int i=1;i<=n;i++) { while(j&&a[i]!=b[j+1]) j=p[j]; if(a[i]==b[j+1]) j++; if(j==m) ans++,j=0; //从头开始重新匹配,保证不重叠 } } int main() { while(scanf("%s%s",a+1,b+1)==2) { n=strlen(a+1),m=strlen(b+1); ans=0; GetP(),KMP(); printf("%d\n",ans); } }
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n,p[N]; char s[N]; void GetP() { p[1]=0; int j=0; for(int i=2;i<=n;i++) { while(j&&s[i]!=s[j+1]) j=p[j]; if(s[i]==s[j+1]) j++; p[i]=j; } } int main() { while(scanf("%s",s+1)) { if(s[1]=='.') break; n=strlen(s+1); GetP(); if(n%(n-p[n])==0) printf("%d\n",n/(n-p[n])); else puts("1"); } }
#include<bits/stdc++.h> using namespace std; const int N=1.5*1e4+5; int n,k,ans,p[N]; char s[N]; int main() { scanf("%s%d",s+1,&k); n=strlen(s+1); for(int l=1;l<=n-2*k;l++) { //枚举子串左端点 p[l]=l-1; int j=l-1,x; for(int i=l+1;i<=n;i++) { //枚举子串右端点 while(j>l-1&&s[i]!=s[j+1]) j=p[j]; if(s[i]==s[j+1]) j++; x=p[i]=j; while(2*(x-l+1)>=i-l+1) x=p[x]; if(x-l+1>=k) ans++; } } printf("%d",ans); }
如有错误请指正。