利用next数组求字符串的最小周期
结论:如果有一个字符串s,长度是len,它的失败函数是next,如果len能被len-next[len]整除,那么len-next[len]就是我们要求的那个子串的长度,与之对应的字符串,就是我们想得到的子串;
poj 1961
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<map>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int nextx[1000010];
char str[1000010];
int len;
void get_next()
{
int i=0,j=-1;
nextx[0]=-1;
while(i<len)
{
if(j==-1||str[i]==str[j])
nextx[++i]=++j;
else
j=nextx[j];
}
}
int main()
{
int n;
int tx=0;
while(cin>>n)
{
if(n==0)
return 0;
getchar();
scanf("%s",str);
cout<<"Test case #"<<++tx<<endl;
len=n;
get_next();
for(int i=2;i<=n;i++)
{
len=i;
int t=len-nextx[len];
if(len%t==0&&len!=t)
cout<<i<<" "<<len/t<<endl;
}
cout<<endl;
}
return 0;
}
给出一个字符串S,长度为len;找出一个前缀一个后缀,使得这两个字符串相同。 输出所有可能的情况
(输出从小到大的长度)
poj 2752
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<map>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int MAX=400010;
int nextx[MAX];
char str[MAX];
int x[MAX];
int len;
void get_next()
{
int i=0,j=-1;
nextx[0]=-1;
while(i<len)
{
if(j==-1||str[i]==str[j])
nextx[++i]=++j;
else
j=nextx[j];
}
}
int main()
{
while(gets(str))
{
len=strlen(str);
get_next();
memset(x,0,sizeof(x));
int k=0;
for(int i=len;nextx[i]!=-1;i=nextx[i])
x[k++]=i;
cout<<x[k-1];
for(int i=k-2;i>=0;i--)
cout<<" "<<x[i];
cout<<endl;
}
return 0;
}