感觉这里讲的挺好的。http://cavenkaka.iteye.com/blog/1569062
就是不断递归next数组。长度不断减小。
题意:给你一个串,如果这个串存在一个长度为n的前缀串,和长度为n的后缀串,并且这两个串相等,则输出他们的长度n。求出所有的长度n。
思路:KMP中的get_next()。对前缀函数next[]又有了进一步的理解,str[1]~~str[next[len]]中的内容一定能与str[1+len-next[len]]~~str[len]匹配(图1)。然后呢我们循环地利用next,由于next的性质,即在图2中若左红串与左绿串匹配,则左红串比与右绿串匹配,因为图1的左红串与右红串是完全相等的。可以保证,每一次得出的字串都能匹配到最后一个字母,也就是得到一个前缀等于后缀。只不过这个字符串的长度在不断地减小罢了。
但是呢。。代码还是用的自己的。因为还是看不太懂别的求next数组的方法。
自己模拟了一下。我的代码应该是没有优化的。
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 using namespace std; 5 6 int next[400005]; 7 char str[400005]; 8 int ans[400000]; 9 10 void getNext(char str[]) { 11 int len=strlen(str+1); 12 next[1] = 0; 13 for (int k=0, q=2; q<=len; ++q) { 14 while(k>0 && str[k+1] != str[q]) 15 k=next[k]; 16 if (str[k+1] == str[q]) 17 k++; 18 next[q] = k; 19 } 20 } 21 22 int main() 23 { 24 while(scanf("%s",str+1)!= EOF) 25 { 26 int len = strlen(str+1); 27 getNext(str); 28 ans[0] = len; 29 int n = 0, i = len; 30 while(next[i]> 0) 31 { 32 n++; 33 ans[n] = next[i]; 34 i = next[i]; 35 } 36 for(i = n; i >= 0; i--) 37 printf("%d ", ans[i]); 38 printf(" "); 39 } 40 return 0; 41 }