主要解决:文本匹配的问题
例子:
文本串:aabaabaaf
模式串:aabaaf
- 暴力匹配 时间复杂度 O(mxn)
- KMP
前缀:不包含尾字母的所有子串(模式串中:a\aa\aab\aaba\aabaa都是)
尾缀:不包含首字母的所有子串模式串中:f\af\aaf\baaf\abaaf都是)
最长相等前后缀:
a | 0 |
aa | 1 |
aab | 0 |
aaba | 1 |
aabaa | 2 |
aabaaf | 0 |
前缀表: aabaaf的前缀表010120
思路:
从模式串第一个字母往后匹配,匹配到f发现不匹配了,就找前一个子串aabaa的最长相等前后缀,根据前缀表知道值为2,因此,跳到模式串下标为2的位置开始重新匹配。(因为前缀与后缀相等,省去了重新匹配前缀的过程)
具体代码实现:
- next/prefix数组都是指的前缀表中存放的内容,但是有些人喜欢将存储时内容整体右移或者数值减1.
即: aabaaf
标准:010120
右移:-101012 : 思路中修改后就是比较的时候不满足的时候找当前冲突位置的下标索引
减1: -10-101-1 : 思路中修改后就是比较的时候不满足的时候找当前冲突位置前一位的下标索引+1
- 代码流程:
- 初始化
- 前后缀不相同的处理
- 前后缀相同的处理
- next数组
- 伪代码:
"""
# file and template
# @project : Code_Server
# @Time : 2020/12/1 14:49
# @Author : twinkle
# @File : KMP主要伪代码.py
# @Software: PyCharm
# @link :
# @introduction:
"""
i后缀末尾 j前缀末尾:j还代表i(包含i)的子串的最长相等前后缀的长度
void getNext(next,s){
j=0
next[0]=0
for(i=1;i<s.size;i++){
# “遇见冲突看前一位”----代码不变量
# 是连续回退的过程,用while,不用if
while s[i]!=s[j] && j>0:
j = next[j-1] # 取前缀表中冲突的前一位的值
# 前后缀相同,继续比较,i在for里后移,j后移
if s[i]==s[j]:
j++
next[i]=j # 更新next
}
}
笔记来源 视频地址:
https://www.bilibili.com/video/BV1PD4y1o7nd
https://www.bilibili.com/video/BV1M5411j7Xx