求模式串在主串中出现的次数,需要理解KMP后才能做,其实还是挺简单的,只要匹配完成一次后,j滑动到next[j]继续比较即可。刚开始一直TLE,上网找别人的代码比对,发现自己多写了一层循环,太粗心了……
/*
* hdu1686/linux.cpp
* Created on: 2011-8-29
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAX_PAR_LEN 10005
#define MAX_TXT_LEN 1000005
char pattern[MAX_PAR_LEN], text[MAX_TXT_LEN];
int nextval[MAX_PAR_LEN], parlen, txtlen;
void get_nextval() {
int i = 0, j = -1;
nextval[0] = -1;
while (i < parlen) {
if (j < 0 || pattern[i] == pattern[j]) {
i++;
j++;
if (pattern[i] != pattern[j]) {
nextval[i] = j;
} else {
nextval[i] = nextval[j];
}
} else {
j = nextval[j];
}
}
}
int kmp() {
int i, j, ret = 0;
get_nextval();
j = i = 0;
while (i < txtlen && j < parlen) {
if (j == -1 || text[i] == pattern[j]) {
i++;
j++;
} else {
j = nextval[j];
}
if (j >= parlen) {
ret++;
j = nextval[j];//本题的关键代码
}
}
return ret;
}
void work() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%s%s", pattern, text);
txtlen = strlen(text);
parlen = strlen(pattern);
printf("%d\n", kmp());
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
work();
return 0;
}