hdu 1686 KMP

求模式串在主串中出现的次数,需要理解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;
}
posted @ 2011-08-29 20:45  moonbay  阅读(165)  评论(0编辑  收藏  举报