c++中有unordered_map和unordered_set这两个数据结构,其内部实现是哈希表,这就要求作为键值的类型必须是可哈希的,比如常见的数据类型int、string等。但在很多应用中我们可能需要用到比较复杂的类型作为键值,比如vector、pair<int,int>,乃至自定义的类,这时候就需要手动编写两个类作为创建该数据结构对象时的参数,具体我们来看一下。
现在我想让pair<int,int>作为unorderd_map的键值,需要编写两个类,每个类中分别包含一个函数,第一个类中的函数叫做哈希函数,将某一个pair<int,int>的对象哈希了,返回其哈希值;第二个叫做相等函数,用于判断两个pair<int,int>对象是否相等,意在解决冲突。
struct Hashfunc {
size_t operator() (const pair<int,int>& key) const{
return hash<int>()(key.first) ^ hash<int>()(key.second);
}
};
struct Equalfunc {
bool operator() (const pair<int,int>& a, const pair<int,int>& b) const{
return a.first == b.first && a.second == b.second;
}
};
以上内容来自c++之复杂类型作为unordered_map的键值
我想要hash Vec3b,这里的hash函数明显不够用,假如两组数字相同,但在Vec3b的顺序不同,hash的结果就相同碰撞了,于是我参考了C++ 自定义哈希函数使得自制数据类型也可使用STL的哈希set,map
所谓hash,就是不同的取值计算的hash值要不同吗,假如Vec3b,要不同其实很简单
假设Vec3b v,满足下式v为不同值时,计算结果不同
b[0]*x+b[1]*y+b[2]*z # 0<=b[0],b[1],b[2]<=255
对于y和z的设计,只需y>255*z,这样b[2]无论如何也不会影响到b[1],这里我看网上推荐质数,所以选择了257,同理x选择了65537,这样可以保证b不同时,hash不同
关于质数的筛选质数生成
代码如下,我这里比较简单是因为b中的元素限定在0~255,不可能撞到吧?
struct Hashfunc4b {
size_t operator() (const Vec4b& key) const {
return size_t(key[0]*65537 + key[1]*257 + key[2]);
}
};