【问题标题】:GetHashCode() from booleans only仅来自布尔值的 GetHashCode()
【发布时间】:2011-10-13 12:18:37
【问题描述】:

我有一个不可变类,其唯一字段是 bool[](大小在运行时确定)。

我怎样才能计算出这个类的一个好的哈希码?通常我只会在每个字段上调用GetHashCode(),并将它们与以下运算符之一组合:+ | &,但由于唯一可能的哈希码是false0true1,那就是真的不会把我带到任何地方。我的实现只需要使用bools,并且必须适用于任意大小的数组。

(可能无关紧要,但我正在使用 C#/.NET 进行编码。)

【问题讨论】:

  • 您是否考虑过BitArray 或取决于大小BitVector32?这将需要更少的实现,如 GetHashCode 等。

标签: c# .net boolean hashcode


【解决方案1】:

简单的bools.GetHashCode() 工作正常,直到您担心性能(在这种情况下使用 Jason 的解决方案)。

【讨论】:

    【解决方案2】:

    假设您的bool[] 被命名为bools

    unchecked { 
        int hash = 17;
        for(int index = 0; index < bools.Length; index++) {
            hash = hash * 23 + bools[index].GetHashCode();
        }
        return hash;
    }
    

    【讨论】:

    • Jason 能解释一下这些数字吗? 17 和 23 是从哪里来的? :-)
    • @Jamie Dixon:这是一种标准实现;关键是乘数是素数。我认为 Java 的 String.getHashCode 非常相似。
    • 这行不通,在不同位置具有相同元素的数组将给出相同的哈希码
    • @mcarbal:首先,它没有。考虑{ false, true }{ true, false }。第一个将给出 23 * (23 * 17 + 0) + 1 的哈希码。第二个将给出 23 * (23 * 17 + 1) + 0 的哈希码。请注意,这些是不同的值。即使所有的值都是false,它仍然会产生一个不同的哈希码(Math.Pow(23, bools.Length) * 17)。其次,你不能期望不同的数组有不同的哈希码。数组 (Math.Pow(2, Int32.Max)) 比哈希码 (Int32.Max - Int32.Min + 1) 多。碰撞必须发生。那么,“行不通”是什么意思?
    • @Jamie,使用非平凡素数可以最大限度地减少简单情况下的冲突概率。例如,作为乘数的 2 会碰撞 1 个假和 33 个假的数组。
    猜你喜欢
    • 2016-07-22
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多