Power Strings POJ2406 KMP 求最小循环节

相比一般KMP,构建next数组需要多循环一次,因为next[j]代表前j-1个字符的最长相同前缀后缀,比如字符串为aab aab aab共9个字符,则next[10]等于前9个字符中最长相同前缀后缀长度,如果字符串是由某个子串比如aab循环而形成的,则next[10]就会等于(字符串长度len-循环子串长度)。但是需要注意aab aab aa这种情况,算出来结果是不能被len整除的,需要特判

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string.h>
 4 #pragma warning ( disable : 4996 )
 5 using namespace std;
 6 
 7 const int inf = 0x3f3f3f3f;
 8 const int maxn = 1e6+5;
 9 const int vspot = 1e6+5;
10 
11 int net[maxn];
12 char str[maxn];
13 int len, plen;
14 
15 void getnext()
16 {
17     memset( net, 0, sizeof(net) );
18     int k = -1, j = 0;
19     net[j] = -1; plen = 0;
20 
21     while ( j < len )
22     {
23         if ( k==-1 || str[j]==str[k] ) 
24         {
25             j++; k++;
26             net[j] = k;
27         }
28         else
29             k = net[k];
30     }
31     plen = net[len];
32 }
33 
34 int main()
35 {
36     while (1)
37     {
38         scanf( "%s", str );
39         if ( str[0]=='.' ) break;
40 
41         len = strlen(str);
42         getnext();
43         if( len % (len-plen)==0 )
44             printf( "%d
", len/(len-plen) );
45         else
46             printf("1
");
47         
48     }
49     return 0;
50 }
View Code
原文地址:https://www.cnblogs.com/chaoswr/p/8618215.html