KMP
作用:字符串查找(在主串T中找模式串P)
关键:fail数组——充当失配函数,记录最长相同前缀和后缀长度
fail作用:已经有一段匹配上,但到某个字符匹配不上了,就可以直接到下一个有前面符合的字符的字符串开始搜。(利用已知的信息加速匹配过程)
时间:线性
注意:fail记录的不是回文子串,是通过循环j(j<i),满足s0——j = si-j——i,不存在就为-1
实现:
fail初始化-1
跟着fail不断往下跳,匹配上就记录
const int maxn = 100;
int fail[maxn];
void getFail(char *P){
int m=strlen(P);
fail[0]=-1;
for(int i=1;i< m;i++){
int j=fail[i-1];
while(j>=0 && P[j+1]!=P[i]){//P[i]和P[fail[i-1]+1]比较,沿着失配函数往前跳
j=fail[j];
}
if(P[j+1]==P[i]){//跳出来,可能是满足匹配,也可能是跳出边界
j++;
}
fail[i]=j;
}
}
int KMP(char *T,char *P){//T为主串,P为模式串
int n=strlen(T),m=strlen(P);
int j=-1;//j记录当前匹配的长度
for(int i=0;i<n;i++){
while(j>=0 && P[j+1]!=T[i]){//计算出最长匹配
j=fail[j];
}
if(P[j+1]==T[i]){
j++;
if(j+1==m){
return i-m+1;//返回匹配的字符的第一个位置,m已经匹配上,故要+1
}
}
}
return -1;//这里是-1,0代表已经匹配成功
}
int main() {
char s[maxn],t[maxn];
cin>>s>>t;
getFail(t);
cout<<KMP(s,t)<<endl;
return 0;
}
样例
aabbabbba
bba
输出
2
拓展KMP:
作用:处理出字符串S的所有后缀与字符串T的最长公共前缀(特殊的字符串的匹配问题)
关键:ne