理解KMP算法

简单理解KMP

本文读者可以获得两方面的知识

  1. 直观理解如何生成部分匹配表(下文简称匹配表),这是KMP算法的核心思想
  2. KMP算法的实现
  • 算法描述
  • naive方法
  • 生成匹配表
  • 使用匹配表(KMP算法)
  • 参考文章

算法描述

输入

  • text
  • pattern

输出

  • text(长串)匹配到的pattern(短串)位置

常见应用

在网页中搜索关键字(常用快捷键ctrl+f)

naive方法

可以使用2层for循环,时间复杂度O(m*n),m/n分别是text和pattern的长度

生成匹配表

只针对pattern

刚开始看KMP算法,总是看不懂的原因就是因为对匹配表的功能理解不深。尤其是试图理解KMP算法时,下一个匹配位置根据匹配表的值进行跳跃,有些人就开始问为什么了。理解匹配表之后,KMP算法自然而然就理解了。

匹配表的构建基于真前缀,真后缀,让我们先理解它们。

对于pattern='abab'来说,真前缀有

a
ab
aba

注意不包括pattern本身abab,这体现了“真”前缀而区别于前缀

同样,真后缀包含

bab
ab
b

可以发现规律:真前缀总以第一个字符开头,真后缀总以最后一个字符结尾

不要小看这个规律,它极大地帮助理解匹配表。(请再次默读一遍啊上述规律)

到了理解KMP算法核心的时候了,我们把pattern拉长以便更好展示,pattern='abcdeeeeabcd',不通过真前缀和真后缀,能不能一眼看出最长匹配,还记得上边提到的规律吗?画张图帮助理解

这样找到的最长匹配就是abcd,是真前缀和真后缀匹配的最优解,时间复杂度为pattern长度的线性时间。KMP算法中的跳跃到下一个位置,简单讲就是图中左边的匹配跳跃到右边的匹配,这就是KMP算法的核心。

使用匹配表(KMP算法)

当理解了上述的匹配表生成,如何使用自然而然。

todo后续补充

参考文章

  • The Knuth-Morris-Pratt Algorithm in my own words
  • Understanding Knuth-Morris-Pratt Algorithm - StackOverflow

你可能感兴趣的:(理解KMP算法)