我的哈希函数有问题吗?
Is something wrong with my hash function
>我正在尝试实现空间哈希,并使用优化空间哈希中的哈希函数进行可变形对象的碰撞检测,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);
}
定义:
#define P1 73856093
#define P2 19349663
#define P3 83492791
#define TABLE_SIZE 2000
我刚刚尝试遍历元素列表,当我尝试将顶点 1、-1、0 放入表中时,它给了我一个 -196 的索引。我的哈希函数在某个地方搞砸了吗?
负数的模是负数。例如:
-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
这实际上是一个有趣的问题,因为模运算结果的符号是编程语言设计者和数学家喜欢争论的东西。
实际上,在ISO C++中,带有负操作数的模运算的符号是实现定义的。聪明的语言既有mod
,也有rem
来捕捉这两种情况。看看维基百科页面和他们的编程语言表。
有趣的是,它是如何被分割的,接近 50:50。
现在问题的解决方案:只需添加一个正模运算。最简单的解决方案是使用 abs(...) % N
,如(-a) mod N + a mod N = 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;
}
相关文章:
- 我关于函数"Assert"的C++代码有问题
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- C++类中的友元函数有问题?
- 虚拟 CTOR 的克隆函数实现是否有问题
- C++有问题的函数,数组到列表
- C++序列计算器x_{n+1} = f(x_n),数学函数有问题
- (c++)无法让 void 函数工作,主.cpp内部的几行也有问题
- 此函数是否对套接字有问题?
- 使用 std::weak_ptr 和别名构造函数中断循环引用:声音或有问题
- C++中的合并函数算法有问题
- 通过初始化列表调用另一个类的构造函数.有问题
- 我的哈希函数有问题吗?
- 我无法创建公共继承的构造函数有问题C++
- 函数和数组有问题
- Assert()函数抛出一个错误——操作符有问题
- 调用函数有问题
- 初学者对类和函数有问题
- Fprintf对函数返回的字符有问题
- c++的析构函数有问题
- 调用带指针的类函数有问题