繁体   English   中英

对象是否可以使用64位gethashcode?

[英]Are 64 bit gethashcode available for objects?

我正在使用字典,并且想覆盖Key的GetHashCode函数。 但是我需要一个64位哈希码。

有什么解决办法吗?

不,你不能。 GetHashCode的签名固定为virtual int GetHashCode()

注意Dictionary<TKey, TValue> 确实使用相同的哈希码处理多个项目。 您可以通过像这样重载GetHashCode来尝试:

public override GetHashCode()
{
    return 0;
}

这样会使字典变慢(它将使在O(n)而不是O(1)的内部搜索)!

Dictionary<,>通过使用Equals方法查看每个对象来处理具有相同键的多个对象(因此这是一个两步过程,首先是GetHashCode ,然后是所有具有相同GetHashCode的项目之间的Equals )。

要将64位GetHashCode更改为32位GetHashCode,您可以简单地:

long hash64 = ....;
int hash32 = hash64.GetHashCode();
return hash32;

:-)

或者,如果您更喜欢长途旅行:

long hash64 = ....;

unchecked
{
    int hash32 = ((int)hash64) ^ ((int)(hash64 >> 32));
    return hash32;
}

如果您有兴趣, 这里说明Dictionary<,>在内部如何工作。 The System.Collections.Generic.Dictionary Class下查看

我已经对Zobrist散列进行了一些研究...看来您应该完全不理会64位碰撞的可能性。 如果要模拟此,可以执行以下操作:

public class HashPiece
{
    public readonly long Hash64;
    public readonly Piece[] Board = new Piece[64];

    public int GetHashCode()
    {
         return Hash64.GetHashCode();
    }

    public bool Equals(object other)
    {
        return this.Hash64 == ((HashPiece)other).Hash64;
    }
}

在此示例中,您没有比较Piece[]数组,只是希望完整的64位哈希正确。 显然,另一个解决方案是:

    public bool Equals(object other)
    {
        HashPiece other2 = (HashPiece)other;

        if (this.Hash64 != other2.Hash64)
        {
            return false;
        }

        return this.Board.SequenceEqual(other.Board);
    }

请注意,我发现一种奇怪的经验 ,即随机数生成器的质量以及所使用的种子值的单个值会影响冲突次数。

我使用下面的代码生成64位HashCode,主要是用来代替长重复字符串。

 public long ComputeHash(String p_sInput)
 {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(p_sInput));
        return BitConverter.ToInt64(hash, 0);
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM