poj2406

View Code
/*Poj2406题解:
if(len%(len-next[len])==0),则重复子串的长度为 len-next[len].
证明如下,next[len]表示到len为止,满足既是前缀子串又是后缀子串的最长长度,
如下图{a,c}
= {b,d}
若len
%(len – next[len])==0,则说明{ a ,b} 的长度可以被{a, d} 的长度整除,同样可以被{b,c}的长度整除。
而此时,由于{b,c}是{b,d}的前缀子串又是后缀子串且保持{a,b}的长度可以被{a,c}整除。
这样,{a,c}就相当于原来的{a,d},而{b,c}就相当于原来的{b,d},通过这样的划分主串在不断减小,同样保持了len
%(len-next[len])==0的性质,不断划分的最后结果就是最后一次划分为2个相当的前后子串即重复子串。
Kmp的精髓:用kmp每次求得的next值就是当前到i为止的前子串与后子串相等的长度。*/

//kmp算法
#include"iostream"
using namespace std;
char s[10000001];
int next[10000001];
int L;
int i,j;
void Index_kmp()
{
while(i<L) //kmp核心算法
{
if(j==0||s[i]==s[j]) //继续比较后继字符
{ ++i; ++j; next[i]=j; }
else
j
=next[j]; //串向右移动
}
}
int main()
{
while(1)
{
scanf(
"%s",s);
if(s[0] == '.') break;
L
=strlen(s);
i
=1; j=0; next[0]=0;

Index_kmp();
if(L%(L-next[L])==0) printf("%d\n",L/(L-next[L]));//形成周期性
else printf("1\n");
}
return 0;
}
posted @ 2011-05-16 20:10  聊聊IT那些事  阅读(639)  评论(0编辑  收藏  举报