POJ 1961 Period KMP算法next数组的应用
题目: http://poj.org/problem?id=1961
很好的题,但是不容易理解。
因为当kmp失配时,i = next[i],所以错位部分就是i - next[i],当s[0]...s[i]是一个周期串时,i-next[i]显然就是一个循环节,这时(i+1) % (i-next[i]) == 0,(因为下标是从0开始的,所以i+1表示前i个字符,也就是字符个数),判断上式是否为0就可以判断是否是周期串,如果是周期串时,(i+1) / (i-next[i]) 显然就是重复的次数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 int n, next[1000010]; 4 char s[1000010]; 5 void kmp_init() 6 { 7 int j = -1; 8 next[0] = -1; 9 for(int i = 1; i < n; i++) 10 { 11 while(j >= 0 && s[j+1] != s[i]) 12 j = next[j]; 13 if(s[j+1] == s[i]) 14 j++; 15 next[i] = j; 16 } 17 } 18 int main() 19 { 20 int item = 0; 21 while(scanf("%d", &n) != EOF && n) 22 { 23 scanf("%s", s); 24 kmp_init(); 25 printf("Test case #%d\n", ++item); 26 for(int i = 1; i < n; i++) 27 { 28 if(next[i] >= 0 && (i+1) % (i-next[i]) == 0) 29 printf("%d %d\n", i+1, (i+1)/(i-next[i])); 30 } 31 printf("\n"); 32 } 33 return 0; 34 }