KMP经典入门题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/devember/article/details/52166125

试着写写题解,不知道以后会不会养成习惯。。。

前一阵子复习KMP,又回去找了几道入门题写写。。。

切水找找1A的感觉orz。以下大致都是一句话+代码的形式。实在是懒。

不过我是复习,本来也没什么好说的。 

hdu 1358 找循环节、求字符串周期,简单题,题面简洁。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int sz=1e6+5;
char s[sz];
int fail[sz];
int main()
{
	int cas=0;
	for(;;)
	{	int n,len,i,p;
		scanf("%d",&n); if(n==0) break;
		scanf("%s",s+1); len=strlen(s+1); 
		printf("Test case #%d\n",++cas);
		fail[0]=-1; fail[1]=0;
		for(i=2;i<=len;i++)
		{	p=fail[i-1];
			while(p>=0&&s[p+1]!=s[i]) p=fail[p];
			if(p<0) fail[i]=0;
			else fail[i]=p+1;
			if(fail[i]&&i%(i-fail[i])==0) printf("%d %d\n",i,i/(i-fail[i]));
		}
		printf("\n");
	}
	return 0;
}

诶,还是顺便说下吧,我的KMP是自己学的,不,应该说是自己理解之后按照自己的思路写的。

然后写成了现在这个样子的完全就和很多资料不同了。。

当然主要差别无非就是,我的数组下标从1开始而一般的从0开始,然后我写的是“fail[]”数组而不是“next[]”数组。。。

我自己喜欢就好啦~


hdu 1686 匹配,求出现次数;与POJ3461是完全相同的题目。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int sz=1e6+4;
char s1[sz],s2[sz];
int fail[sz];
int main()
{
	int cas; cin>>cas;
	while(cas--)
	{	int len1,len2,i,p;
		scanf("%s%s",s1+1,s2+1);
		len1=strlen(s1+1); len2=strlen(s2+1);
		memset(fail,0,sizeof(fail)); fail[0]=-1;
		for(i=1;i<=len1;i++)
		{	for(p=fail[i-1];p>=0&&s1[p+1]!=s1[i];p=fail[p]);
			if(p<0) fail[i]=0;
			else fail[i]=p+1;
		}
		int ans=0;
		for(i=1,p=0;i<=len2;i++)
		{	for(;p>=0&&s1[p+1]!=s2[i];p=fail[p]);
			if(++p==len1){ans++; p=fail[p];}
		}
		printf("%d\n",ans);
	}
	return 0;
}

这大概就是两道经典入门题吧。。

第一次写博客,第一次发代码,先这样。。。我看看效果。。

展开阅读全文

没有更多推荐了,返回首页