先建立字符串的哈希数组
枚举每个子串
********************************************************************
建立基数数组 函数
void fbase()
{
base[0]=1;
for(int i=1;i<maxn;i++)
base[i]=base[i-1]*m;
}
建立字符串哈希数组
void makehashe(char s[])
{
hashe[len]=0;
for(int i=len-1;i>=0;i--)
hashe[i]=hashe[i+1]*m+s[i];
}
枚举+判断
for(int i=1;i<=len;i++)//字符串长度每次增加一,判断是否为周期
{
if(len%i!=0)
continue;//循环节的长度必须要能整除总长度len
ull temp=hashe[0]-hashe[i]*base[i];//temp为长度增加一后,串的哈希值
int j=0;
for(j=i;j<=len;j+=i)//每次后移子串的长度
if(temp!=hashe[j]-hashe[j+i]*base[i])
break;
if(j==len)//如果每次跳跃都匹配 此子串即为周期串
{
n=len/i;
break;
}
}
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef unsigned long long ull;
const int maxn=1000001;
char s[maxn];
ull base[maxn];
ull hashe[maxn];
ull m=23333;
int len;
void fbase()
{
base[0]=1;
for(int i=1;i<maxn;i++)
base[i]=base[i-1]*m;
}
void makehashe(char s[])
{
hashe[len]=0;
for(int i=len-1;i>=0;i--)
hashe[i]=hashe[i+1]*m+s[i];
}
int main()
{
fbase();//建立基数数组
while(scanf("%s",s))
{
if(strcmp(s,".")==0)
break;
len=strlen(s);
int n=0;
makehashe(s);//建立哈希数组
for(int i=1;i<=len;i++)//字符串长度每次增加一,判断是否为周期
{
if(len%i!=0)
continue;//循环节的长度必须要能整除总长度len
ull temp=hashe[0]-hashe[i]*base[i];//temp为长度增加一后,串的哈希值
int j=0;
for(j=i;j<=len;j+=i)//每次后移子串的长度
if(temp!=hashe[j]-hashe[j+i]*base[i])
break;
if(j==len)//如果每次跳跃都匹配 此子串即为周期串
{
n=len/i;
break;
}
}
printf("%d\n",n);
}
return 0;
}