Hash简单理解

简单哈希


当我们对若干复杂信息进行统计时,可以用Hash函数把这些复杂的信息映射到一个容易维护的值域内,因为值域变得简单和范围变小, 会造成两个不同的原始信息被Hash函数映射成同一个值,所以我们要处理这种情况。有一种叫“开散列”解决方案是建立一个邻接表结构,以Hash函数的值域作为表头数组head,映射后的值相同的原始信息被分到同一个表头的链表中的不同部位,链表的节点可以存一些原始信息和数据。
Hash主要有两个操作,一个是计算哈希后的值,第二个是定位到对应链表上依次遍历比较。
建立一个大小等于值域的数组进行统计和映射,其实就是简单的Hash思想。
哈希函数就是(xmodP)+1;P是一个比较大的质数,但不超过N,显然,这个Hash函数吧数列A分成P类,我们可以依次考虑数列中的每个数A[i],定位到head[A[i]]然后遍历并插入。

比如POJ3349 题目链接
我们可以通过哈希每个雪花的边之和来把雪花分成几个不同的类,然后在遍历插入的时候查询该类有没有和当前处理的雪花匹配的,即可快速的找出是否有一样的雪花
代码附上:

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int MAX = 100010;
const int mod = 99991;
 
vector<int> hsh[mod];//如果mod不加 const 会报错不能识别hsh 
int arm[MAX][6];
int n;
bool issame(int a, int b) {//逆时针or顺时针匹配 (我最开始是找一个数两边的值是否相等) 
	for(int i = 0; i < 6; i++) {
		if((arm[a][0] == arm[b][i] && arm[a][1] == arm[b][(i+1)%6] &&
		    arm[a][2] == arm[b][(i+2)%6] && arm[a][3] == arm[b][(i+3)%6] &&
			arm[a][4] == arm[b][(i+4)%6] && arm[a][5] == arm[b][(i+5)%6])
			||
			(arm[a][0] == arm[b][i] && arm[a][1] == arm[b][(i+5)%6] &&
			arm[a][2] == arm[b][(i+4)%6] && arm[a][3] == arm[b][(i+3)%6] &&
			arm[a][4] == arm[b][(i+2)%6] && arm[a][5] == arm[b][(i+1)%6]))
			return true;
	}
	return false;
}
 
int main() {
	scanf("%d", &n);
	long long sum, key;
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < 6; j++) {
			scanf("%d", &arm[i][j]);
		}
	}
	for(int i = 0; i < n; i++) {
		sum = 0;
		for(int j = 0; j < 6; j++) {
			sum += arm[i][j];
		}
		key = sum % mod; 
		for(int k = 0; k < hsh[key].size(); k++) {//如果是空的,就进不去 
			if(issame(i, hsh[key][k])) {//不是空的,就去匹配顺序 
				printf("Twin snowflakes found.\n");
				return 0;
			}
		}
		hsh[key].push_back(i);//第i个放到该key里 (映射关系) 
	}
	printf("No two snowflakes are alike.\n");
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值