题解0010:Oulipo(哈希)
信奥一本通——哈希 里的例题
题目链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1455
题目描述:输入两个字符串a,b,求a在b里出现了多少次。
这就是一道典型的哈希题。
那么,什么是哈希呢?
定义一个把字符串映射到整数的函数 f ,这个f 就称为是哈希函数。
这个函数,可以方便地帮我们判断两个字符串是否相等。
用这个思路去写代码,会感觉比数组模拟什么的方便了许多。
现在开始说题目
我们用哈希函数 s[n]=s[1]*1+s[2]*b^1+s[3]*b^2......+s[n]*b^(n-1) 对字符串进行赋值
然后用 s[n]=s[m]-s[m-n]*b^n 对字符串进行分离
就可以解决这道题了
代码:
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long//用目前计算机存储数的最大值,避免溢出太多出错
#define N 1000010
const int b=31;//b使用一个质数
ull power[N],arr[N],we;
char s1[N],s2[N];
int main(){
int t,i,j,wer;
power[0]=1;
for(i=1;i<=N;i++){
power[i]=power[i-1]*b;
}//预先求出b^n的所有值
scanf("%d",&t);
while(t--){
wer=0;
scanf("%s%s",s1+1,s2+1);//输入两个字符串
int n=strlen(s1+1),m=strlen(s2+1);
arr[0]=0;
for(i=1;i<=m;i++){
arr[i]=arr[i-1]*b+(ull)(s2[i]-'A'+1);
}//套公式求s2的哈希值
we=0;//这里一定要初始化,不然会被后面的值覆盖
for(i=1;i<=n;i++){
we=we*b+(ull)(s1[i]-'A'+1);
}//套公式求s2的哈希值
for(i=0;i<=m-n;i++){
if(arr[i+n]-arr[i]*power[n]==we){//判断哈希值是不是相等
wer++;
}
}
cout<<wer<<endl;
}
}

浙公网安备 33010602011771号