kmp算法next计算方法_【数据结构——串】KMP算法——next数组Python的实现方式

用字符串

匹配字符串
,即判断
是否包含
表示字符串
个字符

next数组本身也是一个记录下标的数组,所以会受到我们对于匹配项编码排序的影响,理论上不连续编码也是可以的,甚至不用数字编码都可行,但是为了编程方便,所以我们才采用了连续的整数进行编码

本文采用如下编码方式,这种编码可以避免出现负数,(可以认为0位置的值为和任意字符都可以匹配的值,所以如果当前位置为0,那就需要j和i都要往前移一位)

348fee69e651825a424cd03d040aca9a.png

假如数组next中,第j个元素的值5,则代表当j位置发生不匹配时,要移动

,直到编码为5的元素对准发生不匹配的位置。(这个是整个算法的核心思想)

由于字符串

每个位置都有可能发生不匹配,所以next的
元素个数刚好等于字符串
的长度。

对于任意字符串

的头两个元素发生不匹配时,都有固定的值,即0,1(与编码方式有关,按本文的编码方式就是0,1)与之匹配,即对于任意数组next其头两个元素都是0和1。

在计算next数组时,我们是逐步将编码变大的,这里将编码记为

逐步变大的过程中,最长公共前后缀子串的增大也
只能是逐步增大的,但是是可以突然减小的,因为可能在
逐步增大过程出现一个前面都没出现过的新字符,这时next会突然降为1

结合这特点,我们设计代码的思路就是:

递增,利用
回溯

计算第

个next值,只需要判断
的值是否和
相等
  1. 相等则
  2. 不相等:则利用
    往回溯,找到相等的元素或者当
    时直接令

注:

代表在上一个位置发生不匹配时的最长前缀中的第一个不匹配元素(文字描述有点困难,有机会做个视频解释下)

6a968465a170e1fcf6887ec11999c87c.png

具体实现代码,主要要考虑的一点就是python中列表的第一个元素下标为0

def 

改进后的KMP

可以看到上面的算法在计算next时其实是不考虑

的值的,都是考虑从
的值,这其实是有可能导致重复计算的,因为假如
,而
所以应该将0移到该位置,但是上述算法在不考虑
取值的情况下,将1移到该位置,也就是
,所以改进算法就是在计算next时考虑当前值

在讲上面KMP算法时,我强调假如数组next中,第j个元素的值5,则代表当j位置发生不匹配时,要移动

,直到编码为5的元素对准发生不匹配的位置。(这个是整个算法的核心思想)

所以和

比较的永远时当前小标为
的值即
,如果
两值相等则该
的nextval就指向
的nextval值,如果
不等,则该
的nextval值就是它自己
的next的值。

注意:是nextval值指向nextval,因为当

相等时,代表
往后(包括j)共
项,和从首项(包括首项)开始往后的
项相等,这时就可以借用之前在计算前几项确定的nextval值,直接表现就是,如果
两值相等则该
的nextval就指向
的nextval值
#改进kmp

确定号next数组之后就是匹配了

def 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值