给出一个字符串A,求A有多少个前缀同时也是后缀,从小到大输出这些前缀的长度
分析:KMP
对于长度为len的字符串,由next的定义知:
A[0]A[1]...A[next[len]-1]=A[len-next[len]]...A[len-1]此时A[0]A[1]...A[next[len]-1]
为一个符合条件的前缀
有A[0]A[1]....A[next[next[len]]-1] = A[len-next[next[len] - next[next[len]]]...A[next[len]-1],
故A[0]A[1]....A[next[next[len]]-1]也是一个符合条件的前缀
故从len=>next[len]=>next[next[len]] ....=>直到某个next[]为0均为合法答案,
注意当首位单词相同时,也为答案。
/*Accepted 2632K 157MS C++ 845B 2012-08-01 16:36:07*/ #include<stdio.h> #include<string.h> #include<stdlib.h> const int MAXN = 400040; char t[MAXN]; int next[MAXN], ans[MAXN], len; void Make_Next() { int i = 0, j = -1; next[0] = -1; len = strlen(t); while(i < len) { if(-1 == j || t[i] == t[j]) { ++ i, ++ j; next[i] = j; } else j = next[j]; } } void print(int ith) { int i = 0; while(ith) { ans[i ++] = ith; ith = next[ith]; } i --; for( ; i >= 0; i --) { printf("%d", ans[i]); if(i) printf(" "); } printf("\n"); } int main() { while(scanf("%s", t) == 1) { Make_Next(); print(len); } return 0; }