算法:KMP字符串匹配
0x01 暴力方法
很容易想到,字符串匹配可以把模式串在文本串上一个个匹配,但是太慢了。
0x02 前缀数组
在kmp算法中,前缀数组很重要,kmp[i]记录的是从模式串开头,截取长度为 \(i\) 的字串后,在该字串中,最长的公共前后缀长度
代码:
for(int i=2;i<=lb;i++){
int j=kmp[i-1];
while(j>0&&b[i]!=b[j+1])j=kmp[j];
if(b[i]==b[j+1])j++;
kmp[i]=j;
}
0x03 模式串匹配
按照前缀数组,一旦失配,模式串向前平移,直到最长前缀与最长后缀重合,大大节省时间复杂度。
代码:
#include<bits/stdc++.h>
using namespace std;
int la,lb;
char a[1000010];
char b[1000010];
int kmp[1000010];
int main(){
scanf("%s%s",a+1,b+1);
la=strlen(a+1);
lb=strlen(b+1);
for(int i=2;i<=lb;i++){
int j=kmp[i-1];
while(j>0&&b[i]!=b[j+1])j=kmp[j];
if(b[i]==b[j+1])j++;
kmp[i]=j;
}
int j=0;
for(int i=1;i<=la;i++){
while(j&&b[j+1]!=a[i])j=kmp[j];
if(b[j+1]==a[i]){
j++;
}
if(j==lb){
printf("%d\n",i-lb+1);
j=kmp[j];
}
}
for(int i=1;i<=lb;i++){
printf("%d ",kmp[i]);
}
return 0;
}

浙公网安备 33010602011771号