KMP算法可以看做上优化版本的暴力的算法。
目标串: “ABCAEFGH”
模式串: "ABCAD"
暴力算法是 :当目标串中的D与模式串的F不匹配的时候 ,使用模式串的“A” 与目标串中的B在比较:
将KMP算法之前 强烈建议去B站:「天勤公开课」KMP算法易懂版_哔哩哔哩_bilibili
这个地址去看下。
.我是看完之后没有搞懂,为什么使用公共前后缀就可以,还有什么公共前后缀,和最大公共前后缀// 以下算是对该视频关于公共前后缀在这个字符串比较过程中,为什么能起到跳过中间段的详解。
那么KMP算法考虑的是 我们能否 直接使用A与A直接进行比较:跳过BC. 这是KMP算法的核心
也就是所谓公共前后缀:通过使用公共前后缀。判定跳过的策略。
KMP算法如下:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
A | B | C | A | E | F | G | H | ||
A | B | C | A | D |
直接这样比较:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |||
A | B | C | A | D | E | F | G | |||
A | B | C | A | D |
那么为什么可以跳过BC, 而不能跳过3位置的A呢???
暴力比较的过程:如下(黄色部分是重点,体现了KMP算法的核心))
图1:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
A | B | C | A | D | E | F | G | ||
A | B | C | A | F |
图2:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
A | B | C | A | D | E | F | G | ||
A | B | C | A | F |
图3:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
A | B | C | A | D | E | F | G | ||
A | B | C | A | F |
在前两个移动中我们可以很容易的返现 上下不相等:那么为什么会不相等???
这就是公共前后缀不一样 。
先把公共前后缀忘掉:
那么我们如果要想能够跳过某一段,必然是以为移动的过程不会出现相等的情况
也就是当出现前面绿色部分上下相等的时候,当我们移动模式串匹配的时候
我们是如何保证绿色圈的上下部分一定不相等??
仔细思考比较的过程,会发现当每次比较的开始位置不一样的时候,我们就不需要再从开始位置比较,那么如何确定下一次比较开始位置一不一样????
这就是公共前后缀的核。
仔细观察就会发现:我们比较的其实就是用前缀和后缀去比较,
用目标串后面3位置,和 模式串前面3个位置比较,用于比较的串是相等的。其实就是用这个串的 前缀(前三个字符) 与目标串的后缀(后三个字符)比较
实际上面第一个图使用ABCA的 BCA部分 (后缀) 和 下面的 ABCA的 ABC(前缀)比较
第二图 是使用ABCA的CA部分(后缀)和ABCA的AB部分(前缀)比较
如果只考虑ABCA部分,上下是相等的。就是用ABCA的 前三个(前缀) 和后三个(后缀)比较
前后两个, 前后一个的,依次比较。
仔细观察这个比较过程,就是我们从前后2个方向,依次截取相同的长度进行比较的(前面截取的叫前缀,后面截取的叫后缀)。
如果不存在前缀与后缀相同(公共前后缀长度为0)。那么实际上不论比较多少次全部不会相同。。
那么最大公共前后缀,实际上就是第一次相同时候取的位置,是最长的。