KMP算法总结
目录
通常的字符串查找
逐个比较字符串,匹配失败重头再来。
- 时间复杂度:O(m*n)
KMP
解决字符串查找 目的:匹配失败时,模式串回退,主串不用回退 在一个字符串(S)中查找一个子串(W)出现的位置。
- 时间复杂度:O(m+n)
- 空间复杂度:O(m)。
示例
|
|
KMP思路
这里的p_start通常情况下,被描述为next数组,它的含义是:字符串在当前位置存在前缀后缀匹配数组的长度,也可以描述为匹配度。 当出现不匹配时,只需要知道前面的字符串的匹配度,就可以知道,下一次匹配时,pattern的开始查找位置。
信息
如 step4时,
- p_index = 7时,pattern[7] = j 与text[18] 不匹配
- 此时前面的匹配度 =next[p_index - 1] = 3
- 匹配度=3,说明对于主串text,前面 t_index = 18前面的3个字符和pattern前面的3个字符一定是匹配的
- 所以,继续查找时,d_index 还是18 不需要回退,只需要从p_index = 3开始匹配即可,如step5 所示
如何获取next数组
pattern为abcdabcyab时匹配度表
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
pattern | a | b | c | d | a | b | c | y | a | b |
next | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 1 | 2 |
|
|
pattern为abcxabcabcxabcxb时匹配度表
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
pattern | a | b | c | x | a | b | c | a | b | c | x | a | b | c | x | b |
next | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 4 | 0 |
index = 14时,前面的对称度是7 。j = 7,p[14] = ‘x’ ,此时,
- 如果要存在对称性,那么对称程度肯定比前面这个c 的对称程度小,如果大那么x就继承前面的对称性了。
- 要找更小的对称,必然在对称内部还存在子对称,而且这个x必须紧接着在子对称之后。
KMP 完整代码
|
|
解说视频
支付宝
微信