我有一些整数向量,我想在c++11中高效地存储在一个unordered_map中我的问题是:
如何最好地存储这些数据并针对.find
查询进行优化?
我想出了以下的hasher:
class uint32_vector_hasher {
public:
std::size_t operator()(std::vector<uint32_t> const& vec) const {
std::size_t ret = 0;
for(auto& i : vec) {
ret ^= std::hash<uint32_t>()(i);
}
return ret;
}
};
然后将对象存储在unordered_map
中,但是我有几个问题
1.多久计算一次散列,仅一次,某个随机数或次数?
1.使用==
和散列函数创建一个 Package 器对象,以便记住散列并避免多次计算它,这样做有意义吗?
在分析时,我注意到我的cpu时间有相当大的一部分花在了无序Map的查找上,这并不是最优的:(
4条答案
按热度按时间qnzebej01#
因此,当不想使用boost时,Michael Blurr的评论导致了下面的散列函数实现:
好像有用。
编辑:see's answer稍微慢一点,但确实产生了更好的散列分布。
q3aa05252#
HolKann当前最高投票答案中的散列函数导致大量向量的高冲突率,这些向量都包含来自小连续分布的元素。
为了解决这个问题,每个元素的位被均匀地分布(算法取自Thomas Mueller's answer)。
6xfqseft3#
boost::hash_combine
足够好,但不是特别好HolKann的答案已经足够好了,但我建议对每个条目使用一个好的哈希值,然后将它们组合起来,问题是
std::hash
不是一个好的哈希值,boost::hash_combine
也不够强大,无法弥补这一点。kqlmhetl4#
我尝试用see's answer来解决leet代码问题。但是对于某些输入,函数会溢出int。所以,我又回到了你的方法。但是,如果你有如下元素,你的函数会引起很多冲突:
{0}, {0, 0}, {0, 0, 0}
等,因为int的hash是数字本身,所有这些hash都是0。我稍微调整了一下,加入了减少碰撞率的索引:
我只是用索引对哈希进行排序,这样
{0}, {0, 0}, {0, 0, 0}
就会产生不同的哈希。这是一个非常糟糕的哈希函数,但它对我的目的有效:P