kmp的理解应用,询问p串在s中出现了多少次。
关键在于,在p[length(p)] 即'/0'也建立转移,在kmp的过程中统计p串的指针多少次到达'/0'即可。
//poj3461
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 1000006;
void gen_fail(char p[], int f[]) {
f[0] = -1;
int i = 0, j = -1;
while (p[i]) {
if (j == -1 || p[i] == p[j]) {
i++; j++;
if (p[i])
f[i] = p[i] == p[j] ? f[j] : j;
else f[i] = j;
}
else j = f[j];
}
}
int num;
int kmp(char s[], char p[], int f[]) {
int i = 0, j = 0;
while (s[i]) {
if (j == -1 || s[i] == p[j]) i++, j++;
else {
j = f[j];
}
if (j >= 0 && !p[j]) num++;
}
return p[j] ? -1 : i - j;
}
char s[MAXN];
char p[MAXN];
int fail[MAXN];
int main()
{
int T; scanf("%d", &T);
while (T--) {
scanf("%s", p);
scanf("%s", s);
gen_fail(p, fail);
num = 0;
kmp(s,p,fail);
printf("%d\n", num);
}
return 0;
}