蒟蒻的第一篇博客(大佬们求罩)。。。
刚学会的kmp算法,还很浅显,请指教
首先尽量用scanf,个人习惯i从1开始,所以读入a+1,b+1。用k.l测长度时也别忘了+1哦!
work用来求next数组(关键字,用nxt),i要从2开始,切记!!!
kmp基本和work算法差不多啦,区别就是把b和b的比较换为a和b的比较。
(欣赏我清新的代码)
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,k,l,num,ans,nxt[1000005];
char a[1000005],b[1000005];
void work()
{
nxt[0]=0;
nxt[1]=0;
for (int i=2;i<=l;i++)
{
int j=nxt[i-1];
while(j&&b[i]!=b[j+1]) j=nxt[j];
if (b[i]==b[j+1]) j++;
nxt[i]=j;
}
}
void kmp()
{
int j=0;
for (int i=1;i<=k;i++)
{
while(j&&a[i]!=b[j+1]) j=nxt[j];
if (a[i]==b[j+1]) j++;
if (j==l) printf("%d\n",i-l+1);
}
}
int main()
{
scanf("%s",a+1);
scanf("%s",b+1);
k=strlen(a+1);
l=strlen(b+1);
work();
kmp();
for (int i=1;i<=l;i++)
printf("%d ",nxt[i]);
//while(1);
return 0;
}
还有个差不多的,求循环节,hdu1358。
把kmp换成了一个循环,注意什么是循环节长度,什么是循环节循环次数。。。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,k,l,num,ans,nxt[1000005];
char a[1000005],b[1000005];
void kmp()
{
nxt[0]=0;
nxt[1]=0;
for (int i=2;i<=n;i++)
{
int j=nxt[i-1];
while(j&&a[i]!=a[j+1]) j=nxt[j];
if (a[i]==a[j+1]) nxt[i]=j+1;
else nxt[i]=0;
}
}
int main()
{
int cnt = 0;
while(1)
{
scanf("%d",&n);
if (n)
{
scanf("%s",a+1);
kmp();
printf("Test case #%d\n", ++ cnt);
for (int i=2;i<=n;i++)
{
if (nxt[i] && (i%(i-nxt[i]))==0) printf("%d %d\n",i,i/(i-nxt[i]));
}
printf("\n");
}
else break;
}
//while(1);
return 0;
}