我需要将一对long long
映射到double
,但我不确定要使用哪种哈希函数。每对可能包含任意两个数字,但实际上它们通常是0
和100
之间的数字(但同样,这不是保证)。
Here是tr1::unordered_map
文档。我开始是这样的:
typedef long long Int;
typedef std::pair<Int, Int> IntPair;
struct IntPairHash {
size_t operator(const IntPair& p) const {
return ...; // how to hash the pair?
}
};
struct IntPairEqual {
bool operator(const IntPair& a, const IntPair& b) const {
return a.first == b.first
&& a.second == b.second;
}
};
tr1::unordered_map<IntPair, double, IntPairHash, IntPairEqual> myMap;
一般来说,我不知道要使用什么哈希函数。什么是一个很好的通用哈希函数?
答案 0 :(得分:11)
散列对的自然方法是以某种方式组合其组件的散列。最简单的方法是使用xor:
namespace std {
namespace tr1 {
template<typename a, typename b>
struct hash< std::pair<a, b> > {
private:
const hash<a> ah;
const hash<b> bh;
public:
hash() : ah(), bh() {}
size_t operator()(const std::pair<a, b> &p) const {
return ah(p.first) ^ bh(p.second);
}
};
}} // namespaces
请注意,这对像(1,1)或(2,2)这样的哈希值都为零,因此您可能希望使用一些更复杂的方法来组合零件的哈希值,具体取决于您的数据。 Boost做了这样的事情:
size_t seed = ah(p.first);
return bh(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2);
答案 1 :(得分:10)
boost::hash形成功能库。
或自己写。最简单的版本= pair.first * max_second_value + pair.second
答案 2 :(得分:2)
建议:看一下这篇SO帖子:"I don't understand std::tr1::unordered_map
"。
此外,Equality Predicates and Hash Predicates上的Boost文档也是一个好地方(以及此example)。
答案 3 :(得分:1)
你真的需要一个基于哈希的地图吗?只要复杂性保证它可以解决您正在解决的问题,基于二叉树的通用映射就可以正常工作。