对于一段字符串来说,如果存在循环节,那么它的最小循环节一定是 ( 字符串的长度i - Next[i] ) (相当于最后一个循环节),那么直接判断(i % ( i - Next[i] ))就可以判断是不是存在循环节,还要注意Next[] > 0
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> using namespace std; const int maxn = 1000005; char str[maxn]; int Next[maxn]; int n ; void KMP() { Next[0] = 0, Next[1] = 0; for(int i = 1; i < n; i++) { int j = Next[i]; while(j && str[i] != str[j]) j = Next[j]; Next[i+1] = (str[i] == str[j] ? j+1 : 0); } } int main() { int cas = 1; while(scanf("%d", &n) == 1 && n) { scanf("%s", str); KMP(); // for(int i = 1 ;i <= n ; i++) cout << i << " " << Next[i] << endl; printf("Test case #%d\n", cas++); for(int i = 2; i <= n; i++) if(Next[i] > 0 && i % ( i - Next[i] ) == 0) printf("%d %d\n", i, i / (i - Next[i])); printf("\n"); } return 0; }