子串查找

来源:互联网 发布:恐怖黎明物品数据官网 编辑:程序博客网 时间:2024/06/06 05:31

Problem B: #103. 子串查找

Time Limit: 5 Sec Memory Limit: 256 MB
Submit: 110 Solved: 44
[Submit][Status][Web Board]
Description

这是一道模板题。

给定一个字符串 A 和一个字符串 B,求 B 在 A 中的出现次数。

A 中不同位置出现的 B 可重叠。

Input

输入共两行,分别是字符串 A 和字符串 B。

Output

输出一个整数,表示 B 在 A 中的出现次数。

Sample Input

zyzyzyz
zyz
Sample Output

3
HINT

1≤A,B 的长度 ≤106 ,A 、B 仅包含大小写字母。

[分析]
很水的题目但是非常的暴露基础。错了好几次。
中间tle一次,然后突然参悟正确的计数方法。(其实还是很开心的)
不过发现,strstr效率没有手写的kmp高,很难受,strstr做5000+ms,kmp20ms。

[strstr代码]

#include<cstdio>#include<cstring>int main(){    char a[10000000];    char b[10000000];    while (scanf("%s%s", a, b) != EOF)    {        char *p = a-1;        int ans = 0;        while (*(p + 1) != '\0' && (p = strstr(p + 1, b)) != NULL)        {            ans++;        }    out:;        printf("%d\n", ans);    }}

[KMP代码]

#include <iostream>#include <cstdio>#include <cstring>const int maxn=1000000+10;using namespace std;char pstring[maxn],tstring[maxn];int plength,tlength;int next[maxn];long long ans=0;void getnext(){    int i,j;    next[0]=-1;    i=0;    j=-1;    while(i<plength)    {        if(j==-1||pstring[i]==pstring[j]){            i++;j++;next[i]=j;        }        else            j=next[j];    }}int kmp(int pos){    int i,j;    i=pos;j=0;    while(i<tlength){        if(j==-1||tstring[i]==pstring[j]){            i++;j++;        }        else            j=next[j];        if(j==plength)            ans++;    }}int main(){    while(~scanf("%s\n%s",tstring,pstring))    {        plength=strlen(pstring);        tlength=strlen(tstring);        ans=0;        if(plength<=tlength)        {            getnext();            kmp(0);        }        printf("%lld\n",ans);    }    return 0;}

[后记]
刚刚查了一下,在网上找了一个解释。
像一般文本找子串strstr是比较快的,像aaaaaaaaaaaaaaaaa找aaaaaaaaaaaaaaaaaaab这种骚数据,KMP是比较快的。所以在OJ上,KMP效率更高。

原创粉丝点击