版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a54665sdgf/article/details/81429914
题目大意:给你两个字符串s1和s2,让你求s2在s1中出现的次数。
kmp:(标准解法)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#define FRER() freopen("i.txt","r",stdin)
#define FREW() freopen("o.txt","w",stdout)
using namespace std;
typedef long long LL;
const int N=10000+10;
const int M=1000000+100;
char s1[M],s2[N];
int nxt[N];
void GetNext(const char* s)
{
int len=strlen(s);
nxt[0]=nxt[1]=0;
for(int i=1,j; i<len; ++i)
{
j=nxt[i];
while(j&&s[i]!=s[j])
j=nxt[j];
nxt[i+1]=s[i]==s[j]?j+1:0;
}
}
int Match(const char* s1,const char* s2)
{
GetNext(s2);
int len1=strlen(s1),len2=strlen(s2);
int cnt=0;
for(int i=0,j=0; i<len1; ++i)
{
while(j&&s1[i]!=s2[j])
j=nxt[j];
if(s1[i]==s2[j])
++j;
if(j==len2)
++cnt;
}
return cnt;
}
int main()
{
//FRER();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",s2,s1);
printf("%d\n",Match(s1,s2));
}
return 0;
}
hash:(能不能AC看脸,只要不是极品非酋就能过)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#define FRER() freopen("i.txt","r",stdin)
#define FREW() freopen("o.txt","w",stdout)
using namespace std;
typedef unsigned long long ll;
const int N=10000+10;
const int M=1000000+100;
const ll p=1e9+7;
char s1[M],s2[N];
int l1,l2;
ll H1[M],H2[N],P[N];
ll Hash(int l,int r)
{
return H1[r]-H1[l-1]*P[r-l+1];
}
int main()
{
//FRER();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",s2,s1);
l1=strlen(s1);
l2=strlen(s2);
H1[0]=H2[0]=0;
for(int i=1;i<=l1;++i)
H1[i]=H1[i-1]*p+s1[i-1];
for(int i=1;i<=l2;++i)
H2[i]=H2[i-1]*p+s2[i-1];
P[0]=1;
for(int i=1;i<=l2;++i)
P[i]=P[i-1]*p;
int cnt=0;
for(int i=1;i<=l1-l2+1;++i)
if(Hash(i,i+l2-1)==H2[l2])++cnt;
printf("%d\n",cnt);
}
return 0;
}