很久以前,我以1.25美元的价格从交易台上买了一本数据结构书.在其中,哈希函数的解释说,由于"数学的本质",它最终应该由质数修改.
你对1.25美元的书有什么期望?
无论如何,我有多年的时间来思考数学的本质,但仍然无法弄明白.
当存在大量的桶时,数字的分布是否真的更均匀?或者这是一个老程序员的故事,每个人都接受,因为其他人都接受它?
什么是好的哈希函数?我在大学的数据结构课程中看到了很多哈希函数和应用程序,但我大多认为很难创建一个好的哈希函数.作为避免碰撞的经验法则,我的教授说:
function Hash(key)
return key mod PrimeNumber
end
Run Code Online (Sandbox Code Playgroud)
(mod是C和类似语言中的%运算符)
使用素数作为哈希表的大小.我觉得这是一个很好的功能,以避免碰撞和快速,但我怎么能做一个更好的?字符串键对数字键有更好的散列函数吗?
我在其他帖子中读到,这似乎是组合哈希值的最佳方式.有人可以打破这一点,并解释为什么这是最好的方法吗?
template <class T>
inline void hash_combine(std::size_t& seed, const T& v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
Run Code Online (Sandbox Code Playgroud)
编辑:另一个问题只是要求神奇的数字,但我想知道整个功能,而不仅仅是这一部分.
有时您需要使用指针的哈希函数; 不是指针指向的对象,而是指针本身.很多时候,人们只是将指针值作为整数,将一些高位切断以使其适合,可能会在底部移出已知零位.事实是,指针值不一定在代码空间中很好地分布; 事实上,如果你的分配器正在完成它的工作,那么它们很可能会聚集在一起.
所以,我的问题是,是否有人开发了对此有益的哈希函数?取一个32位或64位的值,可能在某处获得12位熵,并将其均匀地分布在32位数字空间中.
我有一些整数向量,我想在c ++ 11中的unordered_map中高效存储我的问题是:
如何最好地存储这些并优化.find查询?
我想出了以下的哈希:
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;
}
};
Run Code Online (Sandbox Code Playgroud)
然后将对象存储在unordered_mapI中然而有几个问题
==和哈希函数的包装器对象来记忆哈希并避免多次计算?在进行性能分析时,我注意到我的cpu时间相当大,花费在无序地图上进行查找,这不是最佳的:(
我正在寻找一个将多组整数映射到整数的函数,希望它具有成对独立性等某种保证.
理想情况下,内存使用量将保持不变,并且哈希值可以在插入/删除后的O(1)时间内更新.(这禁止执行诸如排序整数和使用哈希函数之类的操作,如h(x)= h_1(x_1,h_2(x_2,h_3(x_3,x_4))).)
XORing哈希值不起作用,因为h({1,1,2})= h({2})
我认为如果底层哈希函数具有不切实际的强保证(例如n独立性),则将模数乘以模数可能会起作用.
来自Project Euler的问题10 是找到给定n下面所有素数的总和.
我只是通过总结Eratosthenes筛子产生的素数来解决它.然后我通过Lucy_Hedgehog(次线性!)找到了更有效的解决方案.
对于n =2⋅10^ 9:
我在Haskell中重新实现了相同的算法,因为我正在学习它:
import Data.List
import Data.Map (Map, (!))
import qualified Data.Map as Map
problem10 :: Integer -> Integer
problem10 n = (sieve (Map.fromList [(i, i * (i + 1) `div` 2 - 1) | i <- vs]) 2 r vs) ! n
where vs = [n `div` i | i <- [1..r]] ++ reverse [1..n …Run Code Online (Sandbox Code Playgroud) 目前Boost具有hash_combine函数,该函数输出32位无符号整数(确切地说,size_t).一些参考:
http://www.boost.org/doc/libs/1_43_0/doc/html/hash/reference.html#boost.hash_combine
http://www.boost.org/doc/libs/1_43_0/doc/html/hash/combine.html
我想探讨如何创建64位版本的hash_combine.
第一件事是获得64位的黄金比例或任何其他无理数.
第二部分是使用轮班.这部分相当棘手,我想询问是否有最佳实践或指导使用转移来获取哈希值?或者像原始代码一样选择班次:
seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
Run Code Online (Sandbox Code Playgroud)
是随机的?
另外如何评估输出hash_combine以确保它不会产生比原始哈希函数更多的冲突hash_value?
在JavaScript中,是否可以从另一个数字生成一个随机数?
我正在尝试为我的一个分形地形生成器实现一个可预测的随机数生成器.我已经知道可以使用Math.random()生成一个随机数,但我想创建一个随机数生成器,为每个输入生成一个输出.(例如,predictableRandomGenerator(1)总是会产生相同的结果,这不一定与输入相同.)
那么是否可以从另一个数字生成一个随机数,其中每个输入的输出总是相同的?