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':
| 下标 | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| 字符串:ababa | a | b | a | b | a |
| next数组 | 0 | 0 | 1 | 2 | 3 |
所以next数组的每个值,就是来存放从首元素到当前下标元素的子串的最大前后缀。
next数组有什么用?
当我们在进行字符串匹配时,可根据对应的next[i]的值跳过已经匹配过的元素。
再举个例子:
文本串:aabaabaaf
模式串:aabaaf
| 文本串 | a | a | b | a | a | b | a | a | f |
|---|---|---|---|---|---|---|---|---|---|
| 模式串 | a | a | b | a | a | f | |||
| next[] | 0 | 1 | 0 | 1 | 2 | 0 |
因为当前不匹配,那么将根据前面字串的最大相等前后缀来寻找,即f的前一个字符b的next[]的值:为2
| 文本串 | a | a | b | a | a | b | a | a | f | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 模式串 | a | a | b | a | a | f | ||||||
| next[] | 0 | 1 | 0 | 1 | 2 | 0 |