KMP算法的理解

首先参考阮一峰的KMP博文,简单明了。
网上更多的博文讲解next的实现,却很少有博文认真分析为什么需要next,以及next为什么要这样设计,或者说,为什么这么做是可行的。
阮一峰的理解是 如果匹配串头尾有重复的内容,则在匹配失败的情况下,直接从头部移动到尾部。

看完这篇文章以及其他相关文章,我大概知道整个过程该怎么算,但是仍然不明白这个算法的精髓Next数组为什么要这么做,后来用反证法简单的证明了一个困扰了一上午的问题。记录如下:

参考的博文的最后一句话“部分匹配”的实质是,有时候,字符串头部和尾部会有重复。比如,”ABCDAB”之中有两个”AB”,那么它的”部分匹配值”就是2(”AB”的长度)。搜索词移动的时候,第一个”AB”向后移动4位(字符串长度-部分匹配值),就可以来到第二个”AB”的位置 ”

Question:如果中间存在AB,却没有比较,会不会影响结果,例如匹配串如果为“ABCEABFDAB”在CD中间加了EABF,为什么第一个AB不去比较中间的AB,而直接跳到最后的AB,即“为什么直接比较最后一个AB是可行的?

Answer: 反证法,如果存在第一个AB移动到第二个AB的位置后完全匹配到模式串,那么重叠的部分长度就是next[ j ]>2( 这里画图更容易理解)
这和已知的next[ j ]=2矛盾
因此可得,从第一个直接跳转到最后的是可以的,这里就是根据匹配串自身的特征(前缀=后缀的最长长度)。
进一步可得,通过重叠函数分析得到next数组,就是分析匹配串自身的特征,然后移动的过程中,如果遇到已经匹配了部分前缀,可以通过nextStep=j-next[ j ]的方式 避免重复计算!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值