KMP算法原始版与优化

void GetNext(string pattern,int* &next)
{
	int length = pattern.length();    //*前后缀相等的长度越大意味着在该位置回退回去的距离越短,效率越低,next数组内的数字代表当前不匹配,用该数字索引对应的字符重新匹配
	next = new int[length];
	int k = -1, j = 0;	//k代表前缀结尾,j代表后缀结尾
	next[0] = -1;	//很关键,因为next[0]为-1意味着此处没有前缀和后缀
	while(j < length)
	{
		if(k == -1 || pattern[j] == pattern[k])
		{
			next[++j] = ++k;	//j和k先自加1,从next[1]开始写入数据
		}
		else
		{
			k = next[k];	//此次前缀和后缀不匹配,前缀缩小范围,根据已有的next数组信息,可以明确到具体缩小到的位置,即next[k],next[k]本身的意思就是适配的时候应该回到next[k]处重新匹配,刚好满足条件。
		}
	}
}
int KMP(string str,string pattern, int next[])
{
	int strL = str.length();
	int patternL = pattern.length();
	int i = 0, j = 0;
	while(i < strL && j < patternL)
	{
		if(j == -1 || str[i] == pattern[j])	//如果第0位pattern就跟str不匹配,j=next[0]=-1.要考虑此情况
		{
			i++;
			j++;
		}
		else
		{
			j = next[j];
		}
	}
	return	i < strL ? i - j : -1;	//返回-1则未找到匹配位置
}
优化版kmp算法:
void GetNextEX(string pattern,int* &next)
{
	int length = pattern.length();
	next = new int[length];
	int k = -1, j = 0;
	next[0] = -1;
	while(j < length)
	{
		if(k == -1 || pattern[j] == pattern[k])
		{
			j++;
			k++;
			if(pattern[j] == pattern[k])//next[j]=k的含义是,如果在j处匹配失败,则回溯到k重新匹配,可是预判一下,如果模式串里第j个字符跟第k个字符相等,j对应字符都失配了,k对应那个肯定也适配,这种直接继续回溯到next[k],k不用看了
			{
				next[j] = next[k];
			}
			else
			{
				next[j] = k;
			}
		}
		else
		{
			k = next[k];
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值