KMP算法思想 代码实现

KMP是极其经典与有趣的算法,

代码如下

#include<cstdio>
#include<cstring>
using namespace std;
char a[1000010],b[1000010];

int main()
{
	scanf("%s",a);
	scanf("%s",b);
	int n=strlen(a),m=strlen(b);
	int max_len[m]={0};//max_len[i]=j,表示b[i]前的字符串包括b[i]的最长公共前后缀的长度 
	int i,j=1,k=-1;//k表示max_len数组的左指针,j为右指针 
	//左指针表示前缀的最后一个元素,
	//j表示已确定后缀最后一个元素后面待定的元素 
	max_len[0]=0;//b[0]前包括b[0]的字符串的最长公共前后缀为零 ,必然 
//......下面开始造max-len数组,注意,是针对b一个字符串的 
	while(j<m)
	{
		if(b[k+1]==b[j])//k+1与i都是以确定 
		{
			
			max_len[j]=++k+1;
			//k表示以确定的前缀的最后一个元素的坐标,后面的配对了,自然要++k,
			//数组是零开头的,再+1,表示长度 
			j++;
		}
		else if(k+1==0&&b[k+1]!=b[j]){//不配对 ,往后退,直到k=-1, 
			max_len[j]=0;
			j++;
		}
		else{
			k=max_len[k]-1;//数组是长度,-1是下标,数组元素下标为k以前包括k的公共前后缀,给k 
		}
	}
//以上, max_len数组就完成了,上面的配对都是针对于b字符串的,注意下面的都是两个字符串之间的 
	j=0;i=0;
	k=0;
	while(j<n&&i<m)
	{
		k++;
	//	printf("j=%d i=%d max_len[i]=%d\n",j,i,max_len[i]);
		if(a[j]==b[i])//j是a串的下标,i是b串的下标,元素相等,i,j同时加 
		{
		//	printf("(1)\n");	
			if(i==m-1)//i走到头了,其实就已经刻意在a上找到一段b串了,这里没有break,是为了看看有几段b 
			{
				printf("%d\n",j-i+1);//在a的什么位置开始,有b,打印 
				i=max_len[i]-1;
			}
			i++;j++;
		}
		else if(i!=0){//不配对,i!=0,就往后推 
			i=max_len[i-1];
		//	printf("(2)\n"); 
		}
		else {//if(max_len[i]==0),,在初位置不配对,只j++,往后再判断 
		i=0;j++;
	//	printf("(3)\n");
		 
		}	
	}
	for(i=0;i<m;i++) printf("%d ",max_len[i]);
    return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值