KMP算法
代码部分
1 |
|
前言
由于笔者水平有线,对KMP算法的理解只是有限的。如想深入了解建议阅读KMP算法原文。
原理
首先,我们先确定模式串与目标串。模式串:较短的串。目标串:较长的串,被匹配的串。需要再目标串中找到模式串。
KMP算法的原理是在目标串与模式串每个字符的比较循环中,目标串的指针不回溯,通过修改模式串指针来加快匹配速度。那么重点就是怎么处理模式串来达到这个快速匹配。
处理模式串的原理是根据已匹配过的串得知相应的信息,本文最下方参考list中视频讲解对此有很好的解释,建议先看完视频再来看本文(视频只对原理和流程做了解释,但并未对如何求GetLPSArray做解释)。
我自己的理解是,在某个位置字符匹配错误,我们就能知道知道出错索引前的模式串与目标串的字符是相等的,在索引匹配前出错的字符串中如果有出现相同的串,那么就能跳过相同串的匹配来达到加速效果。请见如下例子
暴力匹配流程例子
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
目标串 | a | b | a | b | a | ? | ? |
模式串 | a | b | a | b | c |
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
目标串 | a | b | a | b | a | b | ? |
模式串 | a | b | a | b | c |
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
目标串 | a | b | a | b | a | b | c |
模式串 | a | b | a | b | c |
KMP算法流程
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
目标串 | a | b | a | b | a | ? | ? |
模式串 | a | b | a | b | c | ||
lps | 0 | 0 | 1 | 2 | 0 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
目标串 | a | b | a | b | a | b | c |
模式串 | a | b | a | b | c | ||
lps | 0 | 0 | 1 | 2 | 0 |
我们很容易理解暴力匹配的流程,这里比较难理解的是在 目标串[4]!=模式串[4]时,KMP算法直接将模式串的索引等于2,即目标串[4]开始与模式串[2]开始比较,目标串的索引不回溯。在这里我们能在大脑中轻松想到,在索引=4时,将模式串的索引变为2就能跳过多余的匹配,但要如何用算法描述这个过程请往下看。
GetLPSArray方法
现在重点就是求模式串所对应的lps数组。在上文代码中GetLPSArray方法已写出,现在来具体看看GetLPSArray方法的实现的原理。
敬请期待…
一些串对应的lps例子
例一
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
模式串 | a | b | c | d | a | b | c | x |
lps | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 |
例二
索引 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
模式串 | a | a | b | a | a | c |
lps | 0 | 1 | 0 | 1 | 2 | 0 |
例三
索引 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
模式串 | a | b | a | a | b | c |
lps | 0 | 0 | 1 | 1 | 2 | 0 |
例四
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
模式串 | a | a | c | a | a | a | c |
lps | 0 | 1 | 0 | 1 | 2 | 2 | 3 |
例五
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
模式串 | a | a | a | c | a | a | a | a |
lps | 0 | 1 | 2 | 0 | 1 | 2 | 3 | 3 |
参考list
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 祝某人的博客!
评论