POJ 2406 KMP

链接:

http://poj.org/problem?id=2406

题意:

给你一个字符串,求它的最小循环节,输出循环了多少次

题解:

KMP,next表示模式串如果第i位(设str[0]为第0位)与文本串第j位不匹配则要回到第next[i]位继续与文本串第j位匹配。

则模式串第1位到next[n]与模式串第n-next[n]位到n位是匹配的。

所以思路和上面一样,如果n%(n-next[n])==0,则存在重复连续子串,长度为n-next[n]。

例如:a    b    a    b    a    b

next:-1   0    0    1    2    3    4

next[n]==4,代表着,前缀abab与后缀abab相等的最长长度,这说明,ab这两个字母为一个循环节,长度=n-next[n];

代码:

31 char s[MAXN];
32 int Next[MAXN];
33 
34 void buildNext(char P[]) {
35     int m = strlen(P);
36     int i = 0, j;
37     j = Next[0] = -1;
38     while (i < m) {
39         while (-1 != j && P[i] != P[j]) j = Next[j];
40         Next[++i] = ++j;
41     }
42 }
43 
44 int main() {
45     while (scanf("%s", s) && s[0] != '.') {
46         memset(Next, 0, sizeof(Next));
47         buildNext(s);
48         int n = strlen(s);
49         if (n % (n - Next[n]) == 0) cout << n / (n - Next[n]) << endl;
50         else cout << 1 << endl;
51     }
52     return 0;
53 }

 

posted @ 2017-04-30 18:17  Flowersea  阅读(199)  评论(3编辑  收藏  举报