题解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;
	}	
}

 

 

posted @ 2022-04-23 11:47  uf0_金币灰黄^w.h  阅读(411)  评论(0)    收藏  举报