KMP算法(没有晦涩难懂讲解,含代码,未写完)

197 阅读2分钟

KMP理论部分

KMP算法是一个用来解决字符串匹配的算法,KMP是三位作者的名称缩小,这里就不多赘述,感谢的伙伴自行百度。

1.字符串的前缀、后缀和最长相等前后缀(核心基本概念

  • 前缀除字符串以外一个字符以外的所有头部子串(简单来说就是包含第一个字符,不包含最后一个字符的子串)。 以外

  • 后缀除字符串第一个字符以外的所有尾部子串(简单来说就是包含最后一个字符,不包含第一个字符的子串)。

  • 最长相等前后缀(部分匹配值): 字符串的前缀和后缀的最长相等的长度。(这里有一个小陷阱,很多刚开始接触的小伙伴,会理解成对称的长度,这是错误的)

不理解没关系,看看下面这个例子就懂了

以 'a' -> 'ababa' 为例子:

字符串前缀后缀前后交集最长相等前后缀
'a'0
'ab'{ a }{ b }0
'aba'{ a,ab }{ a,ba }{ a }1
'abab'{ a,ab,aba }{ b,ab,bab }{ ab }2
'ababa'{ a,ab,aba,abab }{ b,ba,aba,baba }{ aba }3

相信你看完一遍后,就能很容易理解上面的基本概念了。

2.Next数组(最核心的概念)

简介

什么是next数组呢?简单来说就是用来记录字符串的子串的最大前后缀,可能这里有点绕口,接着往下看就懂了。

举个例子 'ababa':

下标01234
字符串:ababaababa
next数组00123

所以next数组的每个值,就是来存放从首元素到当前下标元素的子串的最大前后缀。

next数组有什么用?

当我们在进行字符串匹配时,可根据对应的next[i]的值跳过已经匹配过的元素。

再举个例子:

文本串:aabaabaaf

模式串:aabaaf

文本串aabaabaaf
模式串aabaaf
next[]010120

因为当前不匹配,那么将根据前面字串的最大相等前后缀来寻找,即f的前一个字符b的next[]的值:为2

文本串aabaabaaf
模式串aabaaf
next[]010120

KMP代码部分(Java)