本文是介绍 什么是 BF算法、KMP算法、BM算法 三部曲之一。html
KMP算法 内部涉及到的数学原理与知识太多,本文只会对 KMP算法 的运行过程、 部分匹配表 、next数组 进行介绍,若是理解了这三点再去阅读其它有关 KMP算法 的文章确定能有个清晰的认识。算法
如下的文字描述请结合视频动画来阅读~数组
视频地址:https://www.bilibili.com/video/av60334201/ide
Knuth-Morris-Pratt 字符串查找算法,简称为 KMP算法,经常使用于在一个文本串 S 内查找一个模式串 P 的出现位置。动画
这个算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人于 1977 年联合发表,故取这 3 人的姓氏命名此算法。spa
是否是感受 Donald Knuth 这个名字很眼熟?没错,在前面 这或许是讲解 Knuth 洗牌算法最好的文章 一文中也出现了他!3d
下面直接给出 KMP算法 的操做流程:视频
看不明白?直接看动画!htm
如下图文本串 S 与模式串 P 为例:blog
首先,列出模式串 P 的全部子串:
a | |||||||
---|---|---|---|---|---|---|---|
a | b | ||||||
a | b | a | |||||
a | b | a | a | ||||
a | b | a | a | b | |||
a | b | a | a | b | c | ||
a | b | a | a | b | c | a | |
a | b | a | a | b | c | a | c |
而后,求得每个子串的全部前缀与后缀。
前缀 指除了最后一个字符之外,一个字符串的所有头部组合;后缀 指除了第一个字符之外,一个字符串的所有尾部组合。
以第五列为例进行演示。
前缀为
a | |||
---|---|---|---|
a | b | ||
a | b | a | |
a | b | a |
后缀为
b | |||
---|---|---|---|
a | b | ||
a | A | b | |
b | a | a | b |
所以,它的前缀后缀的公共元素的最大长度为 2。
求得原模式串 P 的子串对应的各个前缀后缀的公共元素的 最大长度表 下图。
根据最大长度表 去求 next 数组:next 数组至关于“最大长度值” 总体向右移动一位,而后初始值赋为-1。
好了,获取了 next 数组 后,KMP 算法 的操做就很清晰了。
将模式串 P 与文本串 S 的字母一个个进行匹配,当失配的时候,模式串向右移动。
怎么移动?
好比模式串的 b 与文本串的 c 失配了,找出失配处模式串的 next数组 里面对应的值,这里为 0,而后将索引为 0 的位置移动到失配处。
原文出处:https://www.cnblogs.com/fivestudy/p/11287725.html