KMP算法
KMP算法
字符串算法
给定两个字符串s1和s2,求s2在s1中所有的出现位置
暴力(O(n*m)):
正题 KMP
整体感官
假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置
如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。
换言之,当匹配失败时,模式串向右移动的位数为:失配字符所在位置 - 失配字符对应的next 值,即移动的实际位数为:j - next[j],且此值大于等于1。
原理
利用最大的相同前缀后缀(以下记作maxsame)缩短搜索时间
eg. A B C D A B C
same={A B C}
失配时可利用前后缀相同的性质将短串移动到相同前缀的后一位
next[]
next[]指当失配时将当前长串的匹配位与短串的何位置相对齐
即短串当前匹配位之前所有字符组成的字符串的maxsame长度
第一个取-1
递归求next[]
void getNext(){
int len=strlen(p);
next[0]=-1;
int k=-1;//记忆化 存储当前已有的maxsame长度
int j=0;//当前下标
while(j<len-1){
if(k==-1||p[j]==p[k]){
++k;
++j;
next[j]=k;//把当前匹配位之前所有字符组成的字符串的maxsame长度赋给next
}else{
k=next[k];
}
}
return;
}
若p[j]!=p[k],
将k换成当前maxsame的maxsame再进行匹配
组合到一块
模板:P3375
AC代码: