POJ 2406 Power Strings(字尾陣列或KMP或擴充套件KMP)
阿新 • • 發佈:2018-12-24
題意:
給你一個字串求最多迴圈了多少次(這個題保證了最後一個迴圈節是完整的)
思路:
就是求最小迴圈節,這個問題可以用字尾陣列,KMP,擴充套件KMP都能做出來,不過我個人覺得求最小迴圈節還是擴充套件KMP最好寫了,KMP其次,字尾陣列搞這個反而有點多餘。。。不過既然論文提到了字尾陣列的寫法,那就寫寫好了
首先是擴充套件KMP,在求出擴充套件KMP的next陣列後,找到第一個
對於KMP,如果 n]
對於字尾陣列,列舉長度,如果len%i==0且rak[0]-rak[i]==1且height[rak[0]]==len-i就是一個合格的解,然而這題居然卡倍增的做法,所以程式碼以後補上
錯誤及反思:
程式碼:
首先是擴充套件KMP的做法:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1000100;
int anext[maxn];
char arr[maxn];
void getanext(char *str)
{
int i=0,j,p=1,len=strlen(str);
anext[0]=len;
while(str[i]==str[i+1]&&i+1<len)
i++;
anext[1]=i;
for(i=2;i<len;i++)
{
if(anext[i-p]+i<anext[p]+p)
anext[i]=anext[i-p];
else
{
j=max(anext[p]+p-i,0);
while (i+j<len&&str[j]==str[j+i])
j++;
anext[i]=j;
p=i;
}
}
}
int main(){
while(scanf("%s",arr)&&arr[0]!='.')
{
getanext(arr);
int len=strlen(arr);
for(int i=1;i<=len;i++)
{
if(anext[i]+i==len&&len%i==0)
{
printf("%d\n",len/i);
break;
}
}
}
}
然後是KMP的做法:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int len,nextval[1100000];
char w[1100000];
void get_next(){
int j=0,k=-1;
nextval[0]=-1;
while(j<len){
if(k==-1||w[k]==w[j])
nextval[++j]=++k;
else k=nextval[k];
}
}
int main(){
while(scanf("%s",w)){
if(w[0]=='.') break;
len=strlen(w);
get_next();
int l=len-nextval[len];
if(l!=len&&nextval[len]%l==0)
printf("%d\n",len/l);
else printf("1\n");
}
}