求模式串在待匹配串的出现次数。
Input
第一行是一个数字T,表明测试数据组数。
之后每组数据都有两行:第一行为模式串,长度不大于10000;第二行为待匹配串,长度不大于1000000。所有字符串只由大写字母组成。
Output
每组数据输出一行结果。
Sample Input
4
ABCD
ABCD
ABA
ABABABA
CDCDCDC
CDC
KMP
NAIVE
Sample Output
1
3
0
0
这道题用哈希算法可以做,用KMP则更加方便,现贴出两种ac代码:
hsah:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const long long mod = 1e9+7;
const int MAXN = 1e6+10;
const int MAXM = 1e4+10;
char T[MAXN],W[MAXM];
int main(){
int n;
cin>>n;
while(n--){
scanf("%s %s",&W,&T);
int len1=strlen(W);
int len2=strlen(T);
ll ans=0;
ll s=0;
ll sum=0;
int p=223;
for(int i=0;i<len1;i++){
s=(s*p+W[i]-'A'+1)%mod;
}
for(int i=0;i<=len2-len1;i++){
sum=0;
if(T[i]==W[0]){
for(int j=i;j<i+len1&&j<len2;j++){
sum=(sum*p+T[j]-'A'+1)%mod;
}
if(sum==s){
ans++;
}
}
}
printf("%lld\n",ans);
}
return 0;
}
KMP:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1e6+7;
char W[MAXN],T[MAXN];
int nxt[MAXN];
void getnxt(int m){
int i=1,j=0;
nxt[0]=0;
while(i<m){
if(W[i]==W[j]) nxt[i++]=++j;
else if(!j) i++;
else j=nxt[j-1];
}
}
int kmp(int m,int n){
int i=0,j=0;
int ans=0;
while(i<n){
if(T[i]==W[j]) {
i++;
j++;
}
else if(!j) i++;
else j=nxt[j-1];
if(j==m) ans++;
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%s %s",W,T);
int len1=strlen(W);
int len2=strlen(T);
getnxt(len1);
printf("%d\n",kmp(len1,len2));
}
return 0;
}