您的位置:首页 > 其它

KMP Hihocoder1015 KMP

2015-04-29 11:14 295 查看
Hihocoder1015 KMP

题目链接:http://hihocoder.com/problemset/problem/1015

题意&思路:KMP版

基本上是靠自己试出来的。首先每个位置的fail值代表匹配值,即包括这个字符在内,得到前缀和后缀相同的最大前缀长度。如[0,j],[i-j,j]中设j为3,i为5,则fail[5] = j+1。

用文字叙述KMP流程

产生fail:

设第一个点fail[0] = 0,设j = fail[0];

i从1开始遍历,直到n-1:

循环:若j>0 并且 t[j] != t[i],j = fail[j-1]////注意这里

若t[j] == t[i] j++;

Fail[i] = j;

Match匹配(求所有匹配点):

遇到相同的,向后找;

遇到不相同,j的值变为fail[j-1]直到j为0;

j为n即模式串遍历完毕,记录,j变为fail[j-1];

源码:

#include <cstdio>

#include <cstring>

#include <cmath>

#include <iostream>

#include <algorithm>

using namespace std;

int const MAXT2 = 1000000+5;

int const MAXT1 = 10000+5;

void failure(char *t1,int *fail)

{

fail[0] = 0;

int j = fail[0];

for(int i=1; i<strlen(t1); i++){

while(j && t1[i]!=t1[j])

j = fail[j-1];

if(t1[i] == t1[j]) j++;

fail[i] = j;

}

}

int match(char *t1,char *t2,int *fail)

{

int res = 0,now = 0,j=0;

int n = strlen(t1);

int m = strlen(t2);

while(now + n - j <= m){

if(j == n){

res ++;

j = fail[j-1];

}

while(j && t1[j]!=t2[now]) j = fail[j-1];

if(t1[j] == t2[now]){

j++; now++;

}

else{

now++;

}

}

return res;

}

int main()

{

char t1[MAXT1],t2[MAXT2];

int fail[MAXT1];

int n;

scanf("%d",&n);

while(n--){

scanf("%s%s",t1,t2);

failure(t1,fail);

int ans = match(t1,t2,fail);

printf("%d\n",ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: