哈希函数为3短裤

时间:2012-03-22 05:44:55

标签: hash hashtable hashcode

我必须基于3个短裤创建一个哈希函数。这样做的最佳方法是什么?

编辑 我有一个名为Point的对象。它由三个短路(x,y,z)组成。为了在QSet中使用这个对象,我必须填写以下函数的主体

uint qHash(const Point &point) {
    // return something here that is a unique combination of x, y, z so that
    // it is very quick to calculate and has minimal (if any) hash collisions
}

2 个答案:

答案 0 :(得分:2)

这很大程度上取决于您对哈希函数的需求。

速度是否至关重要?

近乎完美的哈希分布是否至关重要?

您的哈希密钥必须有多大? 32位? 64位?更大?

如果不了解任何其他细节,您可能需要考虑以下几点:

uint hash = (31 * 31 * 31 * (uint)short1) ^ (31 * 31 * (uint)short2) ^ (31 * short3);

这将是快速的,并且应该具有合理的位分布,即使短路的输入值没有很好地分布

<强>更新

修改代码示例以键入uint。如果输入在0到512范围内,我的变体应该可以正常工作。

如果您有兴趣了解为什么我将每个输入乘以31的幂,请参阅

Why does Java's hashCode() in String use 31 as a multiplier?

答案 1 :(得分:1)

如果三条短裤分布相对均匀,您可以使用以下内容:

hashVal = (short1 xor short2 xor short3) modulo numBuckets

这会缩短您的时间,缩短到0numBuckets - 1的特定范围。

这是否合适取决于您的输入值将如何分配以及您对散列函数的期望。

基于你的问题编辑声明散列必须进入无符号整数,并假设一个16位短和32位无符号整数,没有办法完全避免冲突(你需要48位) 。一种可能性是使用:

hashVal = (x leftshift 16) logical-or (y leftshift 8) logical-or (z)

这将合并(逻辑或)您的值:

xxxxxxxxxxxxxxxx0000000000000000
        yyyyyyyyyyyyyyyy00000000
                zzzzzzzzzzzzzzzz

并且至少可以降低相互影响的x/y/z值的可能性。

并且,继续你的评论:

  

我希望我的输入值在0到512的范围内。这会如何影响我的决定?

如果您的输入值被限制在0到512(含)范围内,则每个输入值只需要10位(这将为您提供值0到1023)。在这种情况下,其中三个很容易适合32位无符号整数,因此您可以使用:

hashVal = (x leftshift 20) logical-or (y leftshift 10) logical-or (z)

这提供了完美的哈希,绝对没有碰撞的可能性。