zcmu-1953

来源:互联网 发布:pptv网络电视在线直播 编辑:程序博客网 时间:2024/06/17 07:33

1953: #103. 子串查找

Time Limit: 5 Sec Memory Limit: 256 MB
Submit: 112 Solved: 46
[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 仅包含大小写字母。

思路:题目要求的时间为5秒,这里可以想到srting类的find()函数,时间上5秒够了,但是还是wa几次,没理解到find()函数其实是在找子串的时候,从i个位置开始,比如i=100;要是没找到就跳出循环,因为接下去的再也找不到了,果然还是自己对函数理解不透彻。
另外一个做法是kmp算法,时间耗时小,比较推荐。kmp算法有模板。套一下模板就成了。

ac代码:
string的find()函数;

#include<bits/stdc++.h>using namespace std;int main(){    string a;    string b;    while(cin>>a)    {        getchar();        cin>>b;        int n=a.size();        int m=b.size();        int i=0,count=0;        while(1)        {            i=a.find(b,i);            if(i==-1)break;            if(i!=-1)count++;            i++;        }        cout<<count<<endl;    }    return 0;}
kmp算法:#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=1000001;char a[N],b[N];int la,lb;int p[N];int ans;void makep(){    int j=0;    p[0]=0;    for(int i=1;i<lb;i++)    {        while(j>0&&b[j]!=b[i])            j=p[j-1];        if(b[j]==b[i])            j++;        p[i]=j;    }}void KMP(){    int j=0;    for(int i=0;i<la;i++)    {        while(j>0&&b[j]!=a[i])            j=p[j-1];        if(b[j]==a[i])            j++;        if(j==lb)            ans++,            j=p[j-1];    }    printf("%d",ans);}int main(){    scanf("%s %s",a,b);    la=strlen(a);lb=strlen(b);    makep();    KMP();    return 0;}
原创粉丝点击