KMP(模板)

kmp算法核心思想就是求next数组:那我们就来谈谈next数组
普通next:

void getnext(){
	int j,k;
	j=0;
	k=-1;
	Next[0]=-1;
	int le = strlen(a);
	while(j<le){
		if(k==-1||t[j]==t[k]) Next[++j]=++k;you
		else k=Next[k];
	}
} 

对于普通next,那就有优化的next,但是普通next也有它独特的地方,利用普通next,我们可以求出主串中有多少子串。

int kmpcount(){
	int ans=0;
	int i=0;
	int j=0;
	if(l1==1&&l2==1){//一处优化
		if(s[0]==t[0])
		return 1;
		else return 0;
	}
	getnext();
	for(i=0;i<l1;i++){
		while(j>0&&s[i]!=t[j]) j=Next[j];
		if(s[i]==t[j]) j++;
		if(j==l2){
			ans++;
			j=Next[j];
		}
	}
	return ans;
}

注意:在全局变量最好不要用next,可能会有冲突,用Next就没有了。
优化next

void getnext(){
	int le=strlen(a);
	Next[0]=-1;
	int k=-1;
	int j=0;
	while(j<le-1){
		if(k==-1||a[j]==a[k]){
			j++;
			k++; 
			if(a[j]!=a[k]) Next[j]=k;
			else Next[j]=Next[k];
		}
		else k=Next[k];
	}
	return;
}

这个优化过的next数组,比普通next匹配更快,但这个不能去求主串中子串的个数。

int KMP()
{
	int i=0;
	int j=0;
	int lens=strlen(s);
	int lenp=strlen(p);
	while(i<lens&&j<lenp){
		//如果j=-1(表示第一次开始或者重新开始匹配),即失配于首字符
		if(j==-1||s[i]==p[j]){
			j++;
			i++;
		}
		else{
			//如果j!+-1,或者当前匹配失败 ,则 
			j=Next[j]; // i不变,j=next[j] 
		}
	}
	if(j==lenp)
	return 1;//匹配成功 
	else
	return 0; 
}

ios::sync_with_stdio(0);
	cin.tie(0);

这段代码放在主函数开头,有利解除对cin和cout的安全保护,加快速度,使之接近scanf和printf。

猜你喜欢

转载自blog.csdn.net/weixin_46687179/article/details/106785847