kmp中next数组的含义是:next[i]表示对于s[0]~s[i-1]这个前缀而言,最大相等的前后缀的长度是多少。规定next[0]=-1。
迭代for(int i=next[i];i!=-1;i=next[i]) 就可以得到某个前缀所有长度相等的前后缀的长度。
这题你就暴力枚举整个字符串的所有相等的前后缀,然后暴力判中间的部分是否存在即可。当然使用next数组会很简便。
#include<cstdio> #include<cstring> using namespace std; int next[1000100],T,n; char s[1000100]; void GetFail(char P[],int next[])//next[i]表示s[0]~s[i-1]的前缀中,最大相等的前后缀的长度是多少 { next[0]=-1; int len=strlen(P); for(int i=0;i<len;i++) { int j=next[i]; while(j>=0&&P[i]!=P[j]) j=next[j]; if(j!=-1 && P[i]==P[j]) next[i+1]=j+1; else next[i+1]=0; } for(int i=0;i<len;++i)//左移一位形成最大长度表 next[i]=next[i+1]; } int main() { // freopen("c.in","r",stdin); scanf("%d",&T); for(;T;--T) { scanf("%s",s); n=strlen(s); GetFail(s,next); int E=next[n-1]; while(E) { int k=n-E-1; while(next[k]<E && k>=2*E-1) --k; if(k>=2*E-1) { printf("%d ",E); goto OUT; } E=next[E-1]; } puts("0"); OUT:; } return 0; }