为什么在下面的哈希函数(返回常量0)似乎没有产生任何影响?
由于散列函数返回常量,我期望输出所有值为3.但是,无论我的散列函数是否为常量,它似乎都将std::vector
值唯一映射到唯一值。 / p>
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
// Hash returning always zero.
class TVectorHash {
public:
std::size_t operator()(const std::vector<int> &p) const {
return 0;
}
};
int main ()
{
std::unordered_map<std::vector<int> ,int, TVectorHash> table;
std::vector<int> value1({0,1});
std::vector<int> value2({1,0});
std::vector<int> value3({1,1});
table[value1]=1;
table[value2]=2;
table[value3]=3;
std::cout << "\n1=" << table[value1];
std::cout << "\n2=" << table[value2];
std::cout << "\n3=" << table[value3];
return 0;
}
获得输出:
1=1
2=2
3=3
预期产出:
1=3
2=3
3=3
我对哈希有什么看法?
答案 0 :(得分:14)
您误解了哈希函数的使用:它不用于比较元素。在内部,映射将元素组织到存储桶中,并且散列函数用于确定元素所在的存储桶。使用另一个模板参数执行元素的比较,查看unordered_map
模板的完整声明:
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
哈希之后的下一个模板参数是关键比较器。要获得您期望的行为,您必须执行以下操作:
class TVectorEquals {
public:
bool operator()(const std::vector<int>& lhs, const std::vector<int>& rhs) const {
return true;
}
};
std::unordered_map<std::vector<int> ,int, TVectorHash, TVectorEquals> table;
现在,您的地图将包含一个元素,您的所有结果都将为3
。
答案 1 :(得分:8)
即使存在哈希冲突,理智的哈希表实现也不应丢失信息。有几种技术可以解决冲突(通常将运行时性能与数据完整性进行权衡)。
显然,std::unordered_map
实现了它。
答案 2 :(得分:3)
添加谓词键比较器类。
class TComparer {
public:
bool operator()(const std::vector<int> &a, const std::vector<int> &b) const {
return true; // this means that all keys are considered equal
}
};
像这样使用:
std::unordered_map<std::vector<int> ,int, TVectorHash, TComparer> table;
然后其余代码将按预期工作。