数据结构-KMP算法


本人水平有限,如有理解错误,表达错误,请评论指出,谢谢!



在我的理解,KMP算法最核心的同时最难理解的是这个next()函数。但是,next()的值是挺好求的,难在哪呢?



这个函数难在逻辑。理解起来很费劲,但真的很好用,并且这个函数的结果很好求。例如求模式串T=“ababaaa"的next[j]的函数值


是这样的,当j=0,next[0]=-1,对于任何子串,第一个元素的next()函数值都为-1

当j=1时,next[1]=0;

当j=2时,next[2]=0,因为t1!=t0。

当j=3时,next[3]=1,因为t0=t2。

当j=4时,next[4]=2,因为t0t1=t2t3='ab'。

当j=5时,next[5]=3,因为t0t1t2=t2t3t4='aba'。

当j=6时,next[6]=1,因为t5=t0='a'。

是的,看懂了吗,next[]的值其实就是看子串的前k个值与字串当前位置(没匹配上)的前k个是否相等,next[j]=k。

之后,说完这个函数,可以直接对KMP算法进行总结:

设s为主串,t为模式串,i为主串当前比较字符的下标,j为模式串当前比较字符的下标。令i=start,j初值为0,当si=tj时,i和j分别增加1,再继续比较

否则,i的值不变,j的值改变为next【j】的值再继续比较。这时分俩种情况

1.j 退回到某个j=next【j】值时,Si=Tj,此时i和j分别加1,继续比较

2.j退回到j= -1,令 主串跟模式串的下标各增加1,接着比较Si+1和T0,

这样的循环过程直到下标i大于等于主串,或下标j大于等于模式串t的长度时为止。

KMP算法是一种字符串匹配算法,用于在一个较长的字符串中查找一个较短的模式串。它通过构建next数组来实现快速匹配。 KMP算法的核心思想是在每次失配时,不是将模式串向后移动一位,而是将模式串向后移动至下一次可以和前面部分匹配的位置,从而跳过大部分的失配步骤。这样可以大大提高匹配效率。 next数组是部分匹配表,它存放的是每一个下标对应的部分匹配。部分匹配是指前缀和后缀的最长共有元素的长度。通过构建next数组,可以在匹配过程中根据当前失配的位置快速确定模式串的移动步数。 下面是手动模拟KMP算法的过程: 1. 首先,根据模式串构建next数组。假设模式串为p[],长度为m。初始化next数组,next = -1,next = 0。 2. 从第2个位置开始,依次计算next[i]的。假设已经计算到next[i-1],则比较p[i-1]和p[next[i-1]]的: - 如果p[i-1]等于p[next[i-1]],则next[i] = next[i-1] + 1; - 如果p[i-1]不等于p[next[i-1]],则将next[i-1]的赋给j,然后继续比较p[i-1]和p[j]的,直到找到一个满足p[i-1]等于p[j]的位置或者j等于0为止。此时,next[i] = j。 3. 完成next数组的构建后,开始匹配过程。假设待匹配的字符串为s[],长度为n。初始化i = 0,j = 0。 4. 依次比较s[i]和p[j]的: - 如果s[i]等于p[j],则i和j分别向后移动一位; - 如果s[i]不等于p[j],则根据next数组确定模式串的移动步数。将j移动到next[j]的位置,即j = next[j]。 5. 重复步骤4,直到匹配成功(j等于模式串的长度m)或者遍历完整个字符串s。 通过上述步骤,可以实现高效的字符串匹配。KMP算法的时间复杂度为O(n+m),其中n为字符串s的长度,m为模式串p的长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值