正题
题目链接:
http://poj.org/problem?id=2752
大意
一个字符串,求所有的前缀等于后缀的长度
解题思路
用KMP求出Next数组。然后最大的那个肯定是长度,然后让j=l,之后每次j=next[j],直到j<0。
这里讲解一下原理,首先第一次next[l]是可以理解的因为next[i]表示的就是除了n外最大的前缀等于后缀长度。之后继续往前跳的原理是:
这里拿样例当一下:
ababcabab①|ababcabab②
因为①已经等于②了,所以①的后缀就等于②的后缀,然后②的后缀就是原串中长度为next[l]的后缀,然后这里的next就是求长度小于next[l]的前缀等于后缀的,然后以此类推。
代码
#include<cstdio>
#include<cstring>
using namespace std;
char s[400001];
int l,p[400001],ans[400001],tot;
void ycl()
{p[0]=-1;tot=0;for (int i=1,j=-1;i<=l;i++){while (j>=0&&s[i]!=s[j+1]) j=p[j];if (s[i]==s[j+1]) j++;p[i]=j;}//KMP匹配int j=l-1;while (1){j=p[j];//往后跳if (j<0) break;ans[++tot]=j+1;//记录}while (tot){printf("%d ",ans[tot]);//输出tot--;}printf("%d",l);
}
int main()
{while (scanf("%s",s)!=EOF){l=strlen(s);ycl();printf("\n");}
}