kmp next数组应用。
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=1000000+5; 4 char s[maxn]; 5 int next[maxn]; 6 int snext[maxn]; 7 void get_next(char *T,int len,int *next) 8 { 9 next[0]=-1; 10 for(int i=1;i<=len;i++) 11 { 12 int j=next[i-1]; 13 while(T[i]!=T[j+1]&& j>=0) 14 j=next[j]; 15 if(T[i]==T[j+1])next[i]=j+1; 16 else next[i]=0; 17 } 18 } 19 bool find(char *a,int n,char *b,int m,int *next) 20 { 21 get_next(b,m,next); 22 int j=0; 23 for(int i=0;i<n;i++) 24 { 25 while(j&&b[j]!=a[i]) j=next[j]; 26 if(b[j]==a[i]) j++; 27 if(j==m) return true; 28 } 29 return false; 30 } 31 bool compare(char *a,char *b,int len) 32 { 33 for(int i=0;i<len;i++) 34 if(a[i]!=b[i]) return false; 35 return true; 36 } 37 int main() 38 { 39 int n; 40 while(scanf("%d",&n)!=EOF) 41 { 42 while(n--) 43 { 44 getchar(); 45 scanf("%s",s); 46 int len=strlen(s); 47 get_next(s,len,snext); 48 char *rear=s+len; 49 int cur=snext[len-1]; 50 while(cur>len/3) 51 cur=snext[cur]; 52 int flag=0; 53 for(int i=cur;i>=0;i=snext[i]) 54 { 55 int le=i+1; 56 if(!compare(s,rear-le,le)) continue; 57 if(find(s+le,len-2*le,rear-le,le,next)) {flag=1;printf("%d ",le);break;} 58 } 59 if(!flag) printf("0 "); 60 } 61 } 62 return 0; 63 }