题目链接:https://vjudge.net/contest/247842#problem/E
参考链接:https://blog.csdn.net/u013371163/article/details/60469058
参考链接:https://blog.csdn.net/cryssdut/article/details/24535825
Oulipo
求模式串在待匹配串的出现次数。
Input
第一行是一个数字T,表明测试数据组数。 之后每组数据都有两行:第一行为模式串,长度不大于10000;第二行为待匹配串,长度不大于1000000。所有字符串只由大写字母组成。
Output
每组数据输出一行结果。
Sample Input
4 ABCD ABCD ABA ABABABA CDCDCDC CDC KMP NAIVE
Sample Output
1 3 0 0
不说了,说多了都是泪;
哈稀 sums2=has[i]-has[i-lens1]*vec[ i - lens1 + 1 ];//这个i是随着增大的,错的呜呜呜
应该是这样写的 sums2=has[i]-has[i-lens1]*vec[lens1];
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN=1000010;
typedef unsigned long long ull;
ull has[MAXN];
ull vec[MAXN];
char s1[10005];
char s2[MAXN];
const int base =31;
ull sum=0;
ull sums2=0;
int main(){
int t;
cin>>t;
while(t--){
ull p=1;
sum=0;
scanf("%s",s1+1);
scanf("%s",s2+1);
int lens1=strlen(s1+1);
int lens2=strlen(s2+1);
vec[0]=1;
for(int i=1;i<MAXN;i++){
vec[i]=vec[i-1]*base;
}
for(int i=1;i<=lens1;i++){
sum=sum*base+s1[i];
p*=base;
}
has[0]=0;
for(int i=1;i<=lens2;i++){
has[i]=has[i-1]*base+s2[i];
}
int ans=0;
for(int i=lens1;i<=lens2;i++){
sums2=has[i]-has[i-lens1]*vec[lens1];
if(sum==sums2){
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}