扩展KMP就是说,给出模板串S和串T,长度分别为Slen和Tlen,,求出S[i..Slen-1]与T的最长公共前缀长度,记为extend[i](或者说,extend[i]为满足S[i..i+z-1]==T[0..z-1]的最大的z值)。
扩展KMP可以用来解决很多字符串问题,如求一个字符串的最长回文子串和最长重复子串。
推荐一些自己学习扩展KMP的文章:
- http://blog.youkuaiyun.com/dyx404514/article/details/41831947
- https://segmentfault.com/a/1190000008663857
- https://wenku.baidu.com/view/206c8178d0d233d4b04e69ed.html
不是很理解扩展KMP,我们可以先记住代码嘛,知道扩展KMP可以做啥,怎样使用。随着以后的学习相信自己肯定会理解透的。
模板代码:
const int maxn = 1e4;
/*扩展KMP
* next[i]:p[]的最长公共前缀
* extend[i]:s[i...n-1]与p[]的最长公共前缀
*/
void preEKMP(char *p,int next[]){
int m = strlen(p);
next[0] = m;
int j = 0,k = 1;
while(j+1<m&&p[j]==p[j+1]) j++;
next[1] = j;
for(int i=2;i<m;i++){
int M = next[k]+k-1;
int N = next[i-k];
if(i+N<M+1){
next[i]=N;
}else{
j = std::max(0,M-i+1);
while(i+j<m&&p[i+j]==p[j]) j++;
next[i] = j;
k = i;
}
}
}
void EKMP(char *s,char *p,int next[],int extend[]){
int m = strlen(s);
int n = strlen(p);
int i,j = 0,k = 0;;
preEKMP(p,next);
while(j<m&&j<n&&s[j]==p[j]) j++;
extend[0] = j;
for(int i = 1;i<m;i++){
int M = extend[k]+k-1;
int N =next[i-k];
if(i+N<M+1){
extend[i] = N;
}else{
j = std::max(0,M-i+1);
while(i+j<m&&j<n&&s[i+j]==p[j]) j++;
extend[i] = j;
k = i;
}
}
}