用c语言实现KMP算法

目录

1.关于KMP

2.KMP算法的思路

 3.实现代码:


1.关于KMP

KMP算法与BF算法的作用类似,都可以用来查找模式子串。但是对比于BF算法的蛮力破解,KMP算法用了一种巧妙的方式减少了回溯次数。


2.KMP算法的思路

这里我们用指针i表示指向文本串(父串)str,用指针j表示指向模式串(子串)sub。BF算法是当遇到str【i】!=sub【j】时,i回溯到匹配成功的下一个位置,j回溯到开头。

关于代码可以参考:用c语言实现BF算法_不会敲代码的运气选手^的博客-CSDN博客

KMP算法的神奇之处在于当遇到str【i】!=sub【j】时,i不用回溯,j回溯到一个特殊位置。特殊位置用一个next数组保存。

A.先看看如何手算next数组:

以下图为例:

 

 B.计算机要如何计算next数组呢?

我们不妨先令i=2,k=0;

如果next[i-1]=k,那么next[i]=k+1;

如果next[i-1]!=k,那么k=next[k],对k进行回溯,令k=next[k]。


 3.实现代码:

void getnext(char* sub,int lensub,int* next)
{
	next[0] = -1;
	next[1] = 0;

	//从i==2开始处理
	int i = 2; int k = 0;

	while (i < lensub)
	{
		if (sub[i - 1] == sub[k]||k==-1)
		{
			next[i] = k + 1;
			i++;
			k++;
		}
		else
			//找不到将k回溯重新判断
			k=next[k];
	}
}
int KMP(char* str, char* sub, int lenstr, int lensub,int pos)
{
	//预处理特殊情况
	assert(str&&sub);
	if (pos < 0 || pos >= lenstr)
		return -1;
	if (lensub>lenstr)
		return -1;
	int i = pos; int j = 0;

	//next数组是KMP算法的关键,next数组是用来存子串回溯位置的。
    int* next = (int*)malloc(sizeof(int)*lensub);
	getnext(sub, lensub,next);//处理next数组

	//与bf算法类似
	while (i < lenstr&&j < lensub )
	{
		if (str[i] == sub[j] || j == -1)//将j==-1单独处理防止数组越界
		{
			i++;
			j++;
		}
		else
			//回溯j
			j = next[j];

	}

	if (j>=lensub)
		return (i - j);//找到了,与bf算法结论一样。

	return -1;
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会敲代码的运气选手^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值