整数数组的C#哈希码

fre*_*ith 16 c# arrays algorithm hashcode

我有一个类,内部只是一个整数数组.一旦构造,阵列永远不会改变.我想预先计算一个好的哈希码,以便这个类可以非常有效地用作词典中的键.数组的长度小于约30项,并且整数通常在-1000和1000之间.

Doc*_*own 23

不是很聪明,但足以满足大多数实际目的:

编辑:由于Henk Holterman的评论而改变,谢谢.

int hc=array.Length;
for(int i=0;i<array.Length;++i)
{
     hc=unchecked(hc*314159 +array[i]);
}
return hc;
Run Code Online (Sandbox Code Playgroud)

如果你需要更复杂的东西,请看这里.

  • 看起来不错,但314159可能有点大.像17或31这样的数字也可以很好地完成.并且:`hc = unchecked(hc*SHIFTVAL + array [i]);`独立于编译器设置. (11认同)
  • @chhenning:那又怎样? (3认同)
  • @chhenning 哈希冲突可能会发生,没有人声称这将是“哈希冲突安全”。这是重写“Equals”方法执行操作的地方。据我记得,字典使用“Equals”方法来区分具有相同哈希的对象(这就是为什么“Equals”方法不应该真正作用于哈希本身)。 (2认同)

Blu*_*kMN 6

对于通常在 -1000 到 1000 之间的值数组,我可能会使用以下内容:

static int GetHashCode(int[] values)
{
   int result = 0;
   int shift = 0;
   for (int i = 0; i < values.Length; i++)
   {
      shift = (shift + 11) % 21;
      result ^= (values[i]+1024) << shift;
   }
   return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,我选择了数字 11,因为 11 位是存储 2048 个不同值范围所必需的(-1000 到 +1000 是 2000,这是接近的)。我选择数字 21 是因为 32 位整数减去 11 位等于 21 位。左移 21 位将留下 11 位以包含从 0 到 2048 的值。 (3认同)