kmp算法next计算方法_七分钟理解什么是 KMP 算法

76b144e8eb95ab592213f047208cb0d5.png

本文是介绍 什么是 BF算法KMP算法BM算法 三部曲之一。

KMP算法 内部涉及到的数学原理与知识太多,本文只会对 KMP算法 的运行过程、 部分匹配表next数组 进行介绍,如果理解了这三点再去阅读其它有关 KMP算法 的文章肯定能有个清晰的认识。

以下的文字描述请结合视频动画来阅读~

7edbb19d1f233c034b29c9bcdec6a107.png
https://www.zhihu.com/video/1140625800863752192

定义

Knuth-Morris-Pratt 字符串查找算法,简称为 KMP算法,常用于在一个文本串 S 内查找一个模式串 P 的出现位置。

这个算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人于 1977 年联合发表,故取这 3 人的姓氏命名此算法。

是不是感觉 Donald Knuth 这个名字很眼熟?没错,在前面 这或许是讲解 Knuth 洗牌算法最好的文章 一文中也出现了他!

下面直接给出 KMP算法 的操作流程:

  • 假设现在文本串 S 匹配到 i 位置,模式串 P 匹配到 j 位置
  • 如果 j = -1,或者当前字符匹配成功(即 S[i] == P[j] ),都令 i++,j++,继续匹配下一个字符; 如果 j != -1,且当前字符匹配失败(即 S[i] != P[j] ),则令 i 不变,j = next[j]。此举意味着失配时,模式串 P相对于文本串 S 向右移动了 j - next [j] 位
  • 换言之,将模式串 P 失配位置的 next 数组的值对应的模式串 P 的索引位置移动到失配处

看不明白?直接看动画!

运行过程

以下图文本串 S 与模式串 P 为例:

0f6d18459f8459bb4b91d35194e2fddb.png

首先,列出模式串 P 的所有子串:

9f3276c1da20f035c86d08903afa1866.png

然后,求得每一个子串的所有前缀与后缀。

前缀 指除了最后一个字符以外,一个字符串的全部头部组合;后缀 指除了第一个字符以外,一个字符串的全部尾部组合。

以第五列为例进行演示。

前缀

26098290e33b6b353f00c2535996abe4.png

后缀

441128a4b74835399cd7e0c1d66e5328.png

因此,它的前缀后缀的公共元素的最大长度为 2

求得原模式串 P 的子串对应的各个前缀后缀的公共元素的 最大长度表 下图。

25f0531a21699b6ab2a39a1beca94a78.png

根据最大长度表 去求 next 数组next 数组相当于“最大长度值” 整体向右移动一位,然后初始值赋为-1

a3938c617685fb3cbbc368830bfc7172.png

好了,获取了 next 数组 后,KMP 算法 的操作就很清晰了。

将模式串 P 与文本串 S 的字母一个个进行匹配,当失配的时候,模式串向右移动。

怎么移动?

edd15a56e3df02c834751c9a539048a3.png

比如模式串的 b 与文本串的 c 失配了,找出失配处模式串的 next数组 里面对应的值,这里为 0,然后将索引为 0 的位置移动到失配处。

e65d5a408d792710d3d0ff6e2427739a.png

后记

如果大家看这一章能大概理解 KMP算法 的运行过程的话,那么后续对 KMP算法 的更深入讲解,比如代码实现、next数组优化、时间复杂度分析等知识点肯定也是理解的。

我的专栏:

和程序员小吴一起学算法​zhuanlan.zhihu.com
7e8528af65d017d58ff2fa26d7ee5adf.png
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值