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
GetNext函數的時候可以取得12的next值。i為11時,比較不相等,返回到8,意味著在11的時候,比較不相等,跳轉至8的位置。為什麼跳轉到8呢?因為之前的都相等,而8和11位置處的關系不確定,所以跳至8的位置。當然,可以優化GetNext算法。
//============================================================================ // Name : KMP_hdu1358.cpp // Author : vit // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include#include #include 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]; } }