KMP有什么用
KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。
说人话就是上面第二行的f
那边不相等
然后会跳到b那边
为什么直接跳到b那边了呢?
那么就往前看它的子字符串:aabaa
子字符串的前缀是aa
子字符串的后缀也是aa
那么就找到这个后缀(aa)与之相等的前缀(aa)的后面(b)重新开始匹配
(找最长相等前后缀)
1 | 0 1 2 3 4 5 |
什么是前缀表
什么是前缀
A:只包含首字母不包含尾字母的所有字串
1 | EX:字符串aabaaf |
什么是后缀
A:只包含尾字母不包含首字母的所有字符串
1 | EX:字符串aabaaf |
next数组就是一个前缀表(prefix table)
前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。
什么是前缀表:记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。
要在文本串:aabaabaafa 中查找
是否出现过一个模式串:aabaaf。
a a b a a f
前缀表就是【0,1,0,1,2,0】
最长公共前后缀?
1 | a 0 |
用next数组表示前缀表
1 | void getNext(int* next,const string& s){ |
1 | class Solution{ |
aabaaf
s[j+1] j s[i] s[j+1] s[i] next[0]=-1 now_j
0 -1 1 (a,a) next[1]=now_j=0 0
1 0 2 (a,b) next[2]=next[0]=-1 j=next[0]=-1
0 -1 3 (a,a) next[3]=0 j=j++=0
1 0 4 (a,a) next[4]=1 j++=1
2 1 5 (b,f) next[5]= j=next[1]=0
1 0 5 (a,f) next[5]=-1 j=next[0]=-1
-1 0 -1 0 1 -1
建议手动模拟一边