问题 F: #103. 子串查找
题目描述
这是一道模板题。
给定一个字符串 A和一个字符串 B,求 B 在 A 中的出现次数。
A中不同位置出现的 B 可重叠。
输入
输入共两行,分别是字符串 A 和字符串 B。
输出
输出一个整数,表示 B 在 A 中的出现次数。
样例输入
zyzyzyz
zyz
样例输出
3
提示
1≤A,B 的长度 ≤106 ,A 、B 仅包含大小写字母。
简单KMP模板水题。
因为之前写KMP时next数组有两个计算方式,记得时候记混了,导致错了几次。
#include<stdio.h>
#include<string.h>
int next[1010000];
char s1[1010000],s2[1010000];
int main()
{int i,j,k,m,n,a,b;memset(s1,0,sizeof(s1));memset(s2,0,sizeof(s2));while(scanf("%s%s",s1,s2)!=EOF){memset(next,0,sizeof(next));m=strlen(s1);n=strlen(s2);i=1;j=0;while(i<n)//计算next数组{if(s2[i]==s2[j]){// printf("%c %c\n",s1[i],s1[j]);i++;j++;next[i-1]=j;//注意这一点赋值顺序是在i++和j++之前还是之后}else if(j==0&&s2[i]!=s2[j]){// printf("%c %c\n",s1[i],s1[j]);i++;}else if(j>0&&s2[i]!=s2[j]){// printf("%c %c\n",s1[i],s1[j]);j=next[j-1];}}
// for(i=0;i<=n;i++)
// {
// printf("%d ",next[i]);
// }
// printf("\n");i=0;j=0;int f=0;while(i<m)//KMP算法{if(s1[i]==s2[j]){// printf("%c %c i=%d j=%d\n",s1[i],s2[j],i,j);i++;j++;}else if(j==0&&s1[i]!=s2[j]){// printf("%c %c i=%d j=%d\n",s1[i],s2[j],i,j);i++;}else if(j>0&&s1[i]!=s2[j]){// printf("%c %c i=%d j=%d\n",s1[i],s2[j],i,j);j=next[j-1];}if(j==n)//当j==n时表示第二个字符串在第一个字符串中出现一次{// printf("%d\n",i);j=next[j-1];f++;}}printf("%d\n",f);}return 0;
}