3 aaa 12 aabaabaabaab 0
Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4
一直在思索这个题目,发现自己对next数组理解还是不深刻。
举个简单的例子:
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
str | a | a | b | a | a | b | a | a | b | a | a | b | \0 | |
next[i] | -1 | 0 | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
//============================================================================ // Name : KMP_hdu1358.cpp // Author : vit // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include <string.h> #include <stdio.h> using namespace std; int i, j, m ,n; char str[1000001]; int next[1000001]; int ch; int no; void GetNext() { j = 0; i = -1; next[0] = -1; while (j < n) { if (i == -1 || str[i] == str[j]) { i++, j++; next[j] = i; } else { i = next[i]; } } } int main() { no = 1; while(cin >> n){ if(n == 0) break; scanf("%s", str); GetNext(); printf("Test case #%d\n", no); no++; for(i = 2; i <= n; i++){ ch = i - next[i]; if(i % ch == 0){//可以想成(i - 1) - 0 + 1 if(i / ch > 1){//重复次数大于1 printf("%d %d\n",i,i / ch); } } } printf("\n"); } return 0; }
//优化的算法 void GetNextval(){//用此算法生成的nextval数组,不能用上面的算法进行计算。原因很简单:把相同的串重复跳转判断的部分放在了nextval生成里面,所以减少KMP的比较次数的同时,也造成了无法找到重复串的次数。 j = 0; i = -1; nextval[0] = -1; while(j < n){ if(i == -1 || str[i] == str[j]){ i++, j++; if(str[i] == str[j]) nextval[j] = i; else nextval[j] = nextval[i]; } else i = nextval[i]; } }
原文:http://blog.csdn.net/svitter/article/details/22959285