什么是KMP算法(Knuth-Morris-Pratt 字符串查找算法)?

2019-09-1809:03:40数据结构与算法Comments3,047 views字数 960阅读模式

作者:程序员吴师兄文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

KMP算法 内部涉及到的数学原理与知识太多,本文只会对 KMP算法 的运行过程、 部分匹配表next数组 进行介绍,如果理解了这三点再去阅读其它有关 KMP算法 的文章肯定能有个清晰的认识。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

以下的文字描述请结合视频动画来阅读~文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

七分钟理解什么是 KMP算法

定义

Knuth-Morris-Pratt 字符串查找算法,简称为 KMP算法,常用于在一个文本串 S 内查找一个模式串 P 的出现位置。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

这个算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人于 1977 年联合发表,故取这 3 人的姓氏命名此算法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

是不是感觉 Donald Knuth 这个名字很眼熟?没错,在前面 这或许是讲解 Knuth 洗牌算法最好的文章 一文中也出现了他!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

下面直接给出 KMP算法 的操作流程:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

  • 假设现在文本串 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 的索引位置移动到失配处

看不明白?直接看动画!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

运行过程

以下图文本串 S 与模式串 P 为例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

什么是KMP算法(Knuth-Morris-Pratt 字符串查找算法)?

首先,列出模式串 P 的所有子串:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

aababaabaaabaababaabcabaabcaabaabcac文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

然后,求得每一个子串的所有前缀与后缀。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

前缀 指除了最后一个字符以外,一个字符串的全部头部组合;后缀 指除了第一个字符以外,一个字符串的全部尾部组合。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

以第五列为例进行演示。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

前缀文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

aababaaba文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

后缀文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

babaAbbaab文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

因此,它的前缀后缀的公共元素的最大长度为 2文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

求得原模式串 P 的子串对应的各个前缀后缀的公共元素的 最大长度表 下图。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

什么是KMP算法(Knuth-Morris-Pratt 字符串查找算法)?

根据最大长度表 去求 next 数组next 数组相当于“最大长度值” 整体向右移动一位,然后初始值赋为-1文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

什么是KMP算法(Knuth-Morris-Pratt 字符串查找算法)?

好了,获取了 next 数组 后,KMP 算法 的操作就很清晰了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

将模式串 P 与文本串 S 的字母一个个进行匹配,当失配的时候,模式串向右移动。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

怎么移动?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

什么是KMP算法(Knuth-Morris-Pratt 字符串查找算法)?

比如模式串的 b 与文本串的 c 失配了,找出失配处模式串的 next数组 里面对应的值,这里为 0,然后将索引为 0 的位置移动到失配处。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html

什么是KMP算法(Knuth-Morris-Pratt 字符串查找算法)?
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/suanfa/16484.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/suanfa/16484.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定