初识KMP
KMP算法是一种改进的字符串匹配算法,时间复杂度为O(m+n)。
——百度百科
KMP算法最重要的一个内容就是next数组,它让KMP算法从普通的字符串匹配算法的O(mn)优化到了O(n+m)。
next数组主要的功能就是让两个串匹配失败时,能够快速地找到下一个匹配的地方。
例如:
串A——> ABABABC
串B——> ABA
next数组要求出对于每个next[j],使B[1...k]=B[j-k+1...j]最大的k。
所以就有以下程序:
for(int i=1,j=0;i<m;++i){
while(j&&b[i+1]!=b[j+1])j=next[j];
if(b[i+1]==b[j+1])++j;
next[i+1]=j;
}
这时我们得到的next数组有什么用呢?
for(int i=0,j=0;i<n;++i){
while(j&&a[i+1]!=b[j+1])j=next[j];//当两个位置失配时,j指针就往前跳
if(a[i+1]==b[j+1]){
++j;
if(j==m)printf("%d
",i-j+2);
}
}
其实自己理解一下就行了。
贴代码
#include<bits/stdc++.h>
using namespace std;
const int N=1000005;
char a[N],b[N];
int p[N],n,m;
int main(){
cin>>a+1>>b+1;
n=strlen(a+1),m=strlen(b+1);
for(int i=1,j=0;i<m;++i){
while(j&&b[i+1]!=b[j+1])j=p[j];
if(b[i+1]==b[j+1])++j;
p[i+1]=j;
}
for(int i=0,j=0;i<n;++i){
while(j&&a[i+1]!=b[j+1])j=p[j];
if(a[i+1]==b[j+1]){
++j;
if(j==m)printf("%d
",i-j+2);
}
}
for(int i=1;i<=m;++i)printf("%d ",p[i]);
return 0;
}
HL大佬说KMP其实没什么用,到时候可以用更优的算法来替代。