我的哈希函数有问题

时间:2014-11-28 20:11:53

标签: c++ hashtable collision-detection

我正在尝试实现空间哈希,并使用Optimized Spatial Hashing for Collision Detection of Deformable Objects中的哈希函数,hash(x, y, z) = (x p1 xor y p2 xor z p3) mod n其中n是哈希表中的桶数。

哈希函数的代码是:

int SpatialHash::hash(int x, int y, int z)
{
    return (((x * P1) ^ (y * P2) ^ (z * P3)) % TABLE_SIZE);
}

with definitions:

#define P1 73856093
#define P2 19349663
#define P3 83492791
#define TABLE_SIZE 2000

我只是尝试遍历一个元素列表,当我试图将顶点1,-1,0放入表格时,它给了我一个-196的索引。我用哈希函数搞砸了吗?

3 个答案:

答案 0 :(得分:2)

负数的模数为负数。例如:

-7 % 3 = -1

想要这样的东西代替:

int positiveModulo(int number, int modulo)
{
    int result = number % mudulo;
    if (result < 0)
        result += modulo;
    return result;
}

或者避免分支:

int positiveModulo(int number, int modulo)
{
    int result = number % mudulo;
    result += modulo;
    result %= modulo;
    return result;
}

这会给你:

positiveModulo(-7, 3) = 2

答案 1 :(得分:1)

这实际上是一个有趣的问题,因为模运算结果的符号是编程语言设计者和数学家喜欢争论的东西。

实际上,在ISO C ++中,带负操作数的模运算符号是实现定义的。 聪明的语言有modrem来捕获这两种情况。 查看wikipedia page及其编程语言表。

有趣的是它如何在50:50左右分裂。

现在解决您的问题:只需添加一个正模运算。 最简单的解决方案是使用abs(...) % N作为(-a) mod N + a mod N = 0

答案 2 :(得分:0)

#include <iostream>
#include <vector>
using namespace std;
#define P1 73856093
#define P2 19349663
#define P3 83492791
#define TABLE_SIZE 2000
int positive_mod(int i, int n)
{
    /* constexpr */ int shift = 64*sizeof i - 1;
    int m = i%n;
    return m+ (m>>shift & n);
}
int hasha(int x, int y, int z)
{
    return positive_mod(((x * P1) ^ (y * P2) ^ (z * P3)) ,TABLE_SIZE);
}





int main(int argc, char **argv)
{
    int ret = hasha(1,-1,0);
    cout << ret << endl;
}