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;
}