我创建了一个用于hashTable的整数的hashCode实现,但它们似乎都没有至少关闭均匀分布。那么,假设hashTable的大小接近于100且整数大到几千的大小,那么整数的hashCode的最佳实现是什么?提前谢谢。
答案 0 :(得分:1)
我建议“最佳”实施,无论这意味着什么,几乎可以肯定
Integer.valueOf(value).hashCode()
答案 1 :(得分:1)
由于您的哈希表相当小,因此模数函数将是最简单的实现,如果输入数字是随机的,则分布也应该是随机的。
public int hashCode(int x){
return x%tableSize;
}
更好的实现方法是使用here所述的乘法。
(x*someNumber) % table size;
其他散列函数描述here,检查出来。 希望这会有所帮助。
答案 2 :(得分:1)
如果数据的密钥是均匀分布的,那么只需使用整数本身作为密钥。如果你的密钥没有统一分布,你需要修改整数,使其在所有整数的频谱中更均匀地分布。如何做到这一点取决于密钥的分发方式和确切的Map实现。
你确定你没有做过早的优化吗?在只有100个条目的Map中,如果您有一个恒定的查找时间(完全分布式)或线性查找时间(每个条目都有一个键冲突),那么它确实无关紧要。迭代100项是如此之快,在基准测试之外你很可能不会注意到差异。如果一个列表的平均速度甚至比具有这么小的数据集的地图更快,那将是非常有用的。
答案 3 :(得分:1)
所以你在X轴上有数千的值,你想要"转换"它们在Y轴上的范围小得多,数百。显然你可以除以10或得到模数,但你也希望在目标范围内尽可能均匀地分布它们。
我想你需要一个压缩功能。
例如,您可以将正弦函数应用于输入并乘以散列表的大小。期间应该有什么价值?它取决于:你越接近你期望的输入值,更高的周期(因此两个非常接近的值会产生两个非常不同的结果)。反之亦然:如果输入值预计不会很接近,那么可以用一小段时间。
private int hashCode(int input, int tableSize)
{
return (int)(tableSize*Math.sin(PERIOD*input));
}
答案 4 :(得分:1)
MurmurHash3的最终雪崩函数:
int h = key;
h ^= h >>> 16;
h *= 0x85ebca6b;
h ^= h >>> 13;
h *= 0xc2b2ae35;
h ^= h >>> 16;