题意:统计单串中从某个位置以前有多少重复的串
思路:kmp模板
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define MaxSize 1000005 char str[MaxSize]; int next2[MaxSize]; void GetNext(char t[]){ int j,k,len; j=0; k=-1; next2[0]=-1; len=strlen(t); while(j<len){ if(k==-1||t[j]==t[k]){ ++j; ++k; next2[j]=k; /*优化 if(t[j]!=t[k])next[j]=k; else next[j]=next[k]; */ } else k=next2[k]; } } int KMPIndex(char s[],char t[]){ int i,j,lens,lent; i=j=0; lens=strlen(s); lent=strlen(t); while(i<lens&&j<lent){ if(j==-1||s[i]==t[j]){ ++i; ++j; } else j=next2[j]; } if(j>=lent)return i-lent; else return -1; } int KMPCount(char s[],char t[]){//统计子串在主串中的出现次数,可重叠 int i,j,lens,lent,cnt; i=j=0; lens=strlen(s); lent=strlen(t); cnt=0; while(i<lens){ if(j==-1||s[i]==t[j]){ ++i; ++j; } else j=next2[j]; if(j==lent)++cnt; } return cnt; } void KMPCount2(char t[]){//统计单串中从某个位置以前有多少重复的串 int i,lent,tmp; lent=strlen(t); for(i=2;i<=lent;++i){ tmp=i-next2[i]; if(i%tmp==0&&i/tmp>1) printf("%d %d ",i,i/tmp); } } int main(){ int n,m=0; while(~scanf("%d",&n)&&n){ scanf("%s",str); GetNext(str); printf("Test case #%d ",++m); KMPCount2(str); printf(" "); } return 0; }