洛谷P3375 【模板】KMP字符串匹配

蒟蒻的第一篇博客(大佬们求罩)。。。

刚学会的kmp算法,还很浅显,请指教


首先尽量用scanf,个人习惯i从1开始,所以读入a+1,b+1。用k.l测长度时也别忘了+1哦!

work用来求next数组(关键字,用nxt),i要从2开始,切记!!!


kmp基本和work算法差不多啦,区别就是把b和b的比较换为a和b的比较。


(欣赏我清新的代码)

#include
#include
#include
#include

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
#include
#include
#include

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;
}

你可能感兴趣的:(kmp)