对应章节:串 → 模式匹配 → KMP算法
1. KMP到底解决什么问题
朴素匹配失败后:
主串指针回退
模式串重新从头比较
KMP的核心:
主串指针不回退,只让模式串根据已经匹配的信息跳到合适位置。
2. 为什么能跳
假设模式串前面已经匹配成功一部分:
主串: ... A B C A B X ...
模式串: A B C A B D
前面的:
A B C A B
已经匹配成功。
当:
X != D
朴素算法会让模式串从头重新试。
KMP不会。
它会看已经匹配成功的部分里,有没有:
前缀 = 后缀
如果有,就直接把模式串跳过去继续比较。
3. 什么叫最长相等前后缀
以字符串:
ABABA
为例。
前缀:
A
AB
ABA
ABAB
后缀:
A
BA
ABA
BABA
最长相等前后缀:
ABA
长度:
3
所以发生失配时,可以保留这3个字符已经匹配的信息。
4. KMP真正利用的是什么
KMP利用的是:
模式串自身的结构
也就是提前分析:
哪些前缀和后缀相同
然后得到:
next数组
5. next数组是干什么的
next数组告诉你:
模式串第 j 个字符失配时,下一个应该去比较模式串的哪个位置。
也就是:
失配
↓
查next[j]
↓
模式串跳到新的位置
主串的位置不回退。
6. KMP匹配过程
核心流程:
主串字符 == 模式串字符
→ 两个指针一起后移
主串字符 != 模式串字符
→ 主串不动
→ 模式串根据next跳转
7. 为什么KMP比朴素算法快
朴素算法最坏可能达到:
O(nm)
KMP匹配时主串基本只向前走。
总复杂度通常写:
O(n+m)
其中:
n = 主串长度
m = 模式串长度
8. 408最应该记住的三句话
1. KMP主串指针不回退
2. 失配后模式串按next数组跳
3. next数组来自模式串的最长相等前后缀
9. 一句话总结
KMP就是:前面白匹配的部分不要浪费,利用模式串自己的前后缀关系,失配后直接跳到最可能继续匹配的位置。