蒟蒻的第一篇学习日记(KMP)

网上已经有巨佬写了一篇很详尽的KMP讲解了,我就放个传送门就行了。
这里我就写写我对KMP的理解就ok啦,可能写的很乱。。。
先粘代码:

void getnext(string a)
{
	int len=a.size();
	int k=-1;
	int j=0;
	nxt[0]=-1;
	while(j<len)
	{
		if(k==-1||a[j]==a[k])
		{
			k++;
			j++;
			nxt[j]=k;
		}
		else
		k=nxt[k];
	}
}

理解了这个函数也就理解了如何递推(+递归?)求和后缀相同的最长前缀。精髓是k=next【k】。值得好好推敲。
下面是这篇博客的核心

int getans(string s,string a)
{
	int i=0;
	int j=0;
	int slen=s.size();
	int alen=a.size();
	while(j<slen&&i<alen)
	{
		if(i==-1||a[i]==s[j])
		{
			i++;
			j++;	
		}
		else
		i=nxt[i];
	}
	if(i==alen)
	return j-i;
	else 
	return -1;
}

之前我想着next数组求完了之后就可以为所欲为了 (不就是个比对吗?) 随便写写就写成了下面的这样

void getans(string s,string p)
{
	int slen=s.size();
	int plen=p.size();
	int i=0;
	int j=0;
	while(j<slen&&i<plen)
	{
		i=0;
		while(s[j]==p[i]&&i<plen&&j<slen)
		{
			i++;
			j++;
		}
		if(j==slen)
		break;
		j-=Next[i];
	}
	if(i==plen)
	{
		ans++;
		return ;
	}
}

在洛谷上交了个板子发现没什么问题,回来对比一下大佬的板子发现出入很大。当时没细想,现在再看看终于意识到自己和大佬的差距了。
先不说两层while有多容易翻车,在算法的效率上都错了十万八千里。大佬的代码思想是母串对已经搜过的部分不再重复搜索(小常数*母串长度的复杂度),我的想法是回到上一个可能匹配成功的地方(对暴力的简单优化)。
举个栗子:
母串: asdasdasdasdc
模板串: asdasdc
跑一下就发现问题了,细节决定成败啊。·

你可能感兴趣的:(蒟蒻的第一篇学习日记(KMP))