KMP
kmp
一个字符串操作,快速在主串中寻找模式串。
我们先看一下暴力寻找方法:
暴力
从主串中一个一个寻找模式串的起点,然后按照起点向后枚举每个模式串与主串的字符
时间复杂度:
\(O(nm)\)
其中n为主串长度,m为模式串长度,在最慢情况下。
KMP
我们发现在暴力情况下极限长度会炸,所以就用到了KMP。
我们发现在匹配时如果先匹配成功了一些字符,那么在移动时就可以直接移动成功匹配的长度,
那么,KMP本质上就是求以当前字符为结尾最长相同的后缀和前缀的子串的长度(即最长公共前后缀)
我们通过求next[i]:以i为结尾的后缀和前缀最长相同的子串的长度(不能包含自己),
就能得到每次向后移动的距离。
模版code:
//#pragma GCC optimize("O2")
#include<bits/stdc++.h>
using namespace std;
const int N=100010,M=1000010;
int n,m;
char p[N],s[M];
int ne[N];
int main(){
cin>>n>>p+1>>m>>s+1;
for(int i=2,j=0;i<=n;i++){
while(j&&p[i]!=p[j+1]){
j=ne[j];
}
if(p[i]==p[j+1]){
j++;
}
ne[i]=j;
}
for(int i=1,j=0;i<=m;i++){
while(j&&s[i]!=p[j+1]){
j=ne[j];
}
if(s[i]==p[j+1]){
j++;
}
if(j==n){
cout<<i-n<<" ";//匹配地址
j=ne[j];
}
}
return 0;
}

浙公网安备 33010602011771号