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 }