[终于有感觉了]字符串匹配的KMP算法
Matrix67大牛写的非常生动,推荐大家看看他的。
以下是连接:http://www.matrix67.com/blog/archives/115
我要说的是Matirx67大牛没有提到的预处理数组的再度优化。
对于当前假设A串到了i,B串到了j,然而A[i+1]≠B[j+1],那么j变成f[j],但是如果B[f[j]+1]依旧不等于A[i+1],那么我们还要继续找。但是这个我们可以预处理出来,经过这个处理,去除了很多匹配中的无效对比,速度增快。详见下面的Ff函数。
//将B串和A串进行多次匹配并输出匹配成功位置
//by Sephiroth Lee
//date: 10/8/2010
#include <stdio.h>
#include <string.h>
#define MAXN 100010 //最大长度
char A[MAXN],B[MAXN];
int f[MAXN],n,m,tot;
void Init() {//读入数据
scanf("%s%s",A,B);
n = strlen(A);
m = strlen(B);
memmove(A + 1,A,sizeof(char)*n);
memmove(B + 1,B,sizeof(char)*m);
}
void Init_f() {//初步预处理
int k=0;
for (int i = 2;i <= m;++i) {
while ((k > 0) && (B[k + 1] != B[i]))
k = f[k];
if (B[k + 1] == B[i])
++k;
f[i] = k;
}
}
void Ff() {//f数组优化
Init_f();
int k;
for (int i = 1;i <= m;++i) {
k = f[i];
while ((k > 0) && (B[k + 1] == B[i + 1]))
k = f[k];
f[i] = k;
}
}
void Solve() {//进行匹配
Ff();
int k = 0;
for (int i = 1;i <= n;++i) {
while ((k > 0) && (B[k + 1] != A[i]))
k = f[k];
if (B[k + 1] == A[i])
++k;
if (k == m) {
++tot;
printf("%d\n",i-m+1);
}
}
printf("%d\n",tot);
}
int main() {//主函数
freopen("sample.in","r",stdin);
freopen("sample.out","w",stdout);
Init();
Solve();
return 0;
}
浙公网安备 33010602011771号