Day 5_2 哈希

1.哈希定义和整数的散列

空间换时间
给定两个序列,长度分别为n,m,查询后m个数是否在前面n个数中出现过

#include<stdio.h>
const int maxn = 100010;
bool hashTable[maxn] = {false}; 
int main(){
	int m,n,x;
	scanf("%d%d",&n,&m);
	for(int i = 0;i<n;i++){
		scanf("%d",&x);
		hashTable[x] = true;
	}
	for(int i = 0;i<m;i++){
		scanf("%d",&x);
		if(hashTable[x] == true)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
} 

但是数据不是整数,如字符串则难以处理,所以这时候就用上散列,散列浓缩成一句话:将元素通过函数转换成一个整数,是的该整数尽量唯一地代表这个元素,这个函数称为散列函数H

1) 常用哈希函数

  1. 直接定址法
    H(key) = key 或者线性变换 H(key) = a * key + b

  2. 平方取中法
    取key的平方的中间的若干位作为hash值

  3. 除留余数法
    H(key) = key % mod (mod尽量取素数),当两个数的H(key)也就是hash值相同时会产生冲突,需要想办法让第二个key生成新的hash值,下列为解决冲突办法
    1)线性探查法:hash+1是否空,不是则使用这个位置,是则hash+2判断(循环)
    2)平方探查法:同理,平方变换,H(key) +1^2, H(key) -1^2, H(key) +2^2, H(key) -2^2等等
    3)链地址法:将所有H(key)相同的key连成一个单链表
    ……

2.字符串hash初步

将一个字符串映射为一个整数,a-z或A-Z,对应0-25,25进制数,在转换成十进制数,每个字母唯一对应一个整数,转换的整数最大为26^len - 1。

  1. 例如只有A-Z时,A-Z对应0-25
int hashTable(char S[],int len){
	int id = 0;
	for(int i = 0;i<len;i++){
		id = id * 26 + (S[i] - 'A');
	}
	return id;
}
  1. 含有a-z时,对应26-51,相应转为52进制数
int hashTable(char S[],int len){
	int id = 0;
	for(int i = 0;i<len;i++){
		if(S[i] >= 'A' && S[i] <= 'Z')
			id = id * 52 + (S[i] - 'A');
		else if(S[i] >= 'a' && S[i] <= 'z')
			id = id * 52 + (S[i] - 'a') + 26;
	}
	return id;
}
  1. 含有数字
    两种处理方式:一是增大到62进制数,二是若是字符串的末尾是确定个数的数字,则将前面字母转换为52进制数,后面数字直接拼接,例如BCD4, BCD 转换为 731 ,则整个字符串转换为 7314 ,下面代码则是具体实现
int hashTable(char S[],int len){
	int id = 0;
	for(int i = 0;i<len-1;i++){
		id = id * 26 + (S[i] - 'A');
	}
	id = id * 10 + (S[len-1] - '0') ; 

具体实例:
给定N个字符串,再给M个查询字符串,问每个查询字符串在N个字符串中出现的次数

#include<stdio.h>
int hashTable1(char S[],int len){
	int id = 0;
	for(int i = 0;i<len;i++){
		id = id * 26 + (S[i] - 'A');
	}
	return id;
}
int hashTable2(char S[],int len){
	int id = 0;
	for(int i = 0;i<len;i++){
		if(S[i] >= 'A' && S[i] <= 'Z')
			id = id * 52 + (S[i] - 'A');
		else if(S[i] >= 'a' && S[i] <= 'z')
			id = id * 52 + (S[i] - 'a') + 26;
	}
	return id;
}
int hashTable3(char S[],int len){
	int id = 0;
	for(int i = 0;i<len-1;i++){
		id = id * 26 + (S[i] - 'A');
	}
	id = id * 10 + (S[len-1] - '0') ; 
	return id;
}
const int maxn = 100;
char S[maxn][5],temp[5];
int hashTable[26*26*26 + 10]; 
int hashFunc(char S[],int len){
	int id = 0;
	for(int i = 0;i<len;i++){
		id = id * 26 + (S[i] -'A');
	}
	return id;
}
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 0;i<n;i++){
		scanf("%s",S[i]);
		int id = hashFunc(S[i],3);
		hashTable[id]++;
	}
	for(int i = 0;i<m;i++){
		scanf("%s",temp);
		int id = hashFunc(temp,3);
		printf("%d\n",hashTable[id]);
	} 
	return 0;
} 
发布了26 篇原创文章 · 获赞 3 · 访问量 210

猜你喜欢

转载自blog.csdn.net/qq_41898248/article/details/103767143