如何为自定义数据结构创建哈希码?

问题描述 投票:6回答:3

我制作了一个自定义的“坐标”数据结构,该结构根据特定系统定义了对象的位置。

坐标定义如下:

public class Coordinate
{
    public int X;
    public int Y;
    private int face;
    public int Face
    {
        get { return face; }
        set
        {
            if (value >= 6 | value < 0)
                throw new Exception("Invalid face number");
            else
                face = value;
        }
    }
    private int shell;
    public int Shell
    {
        get { return shell; }
        set
        {
            if (value < 0)
                throw new Exception("No negative shell value allowed");
            else
                shell = value;
        }
    }

    public Coordinate(int face, int x, int y, int shell)
    {
        this.X = x;
        this.Y = y;
        this.face = face;
        this.shell = shell;
    }

    public static Coordinate operator +(Coordinate a, Coordinate b)
    {
        return new Coordinate(a.Face + b.Face, a.X + b.X, a.Y + b.Y, a.Shell + b.Shell);
    }

    public override bool Equals(object obj)
    {
        Coordinate other = (obj as Coordinate);
        if (other == null)
            return false;
        else
            return (Face == other.Face && Shell == other.Shell && X == other.X && Y == other.Y);
    }
}

或者,总而言之,它包含一个int面(0到5),一个int X,一个int Y和一个int Shell。 X,Y和Shell都绑定在下面的0(含0)以下。

我完全没有哈希码方面的经验。我需要比较它们是否相等。我试过了:

private const int MULTIPLIER = 89;

[...]

int hashCode = 1;
hashCode = MULTIPLIER * hashCode + obj.X.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Y.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Face.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Shell.GetHashCode();
return hashCode;

去掉我在谷歌搜索时发现的东西。但是当我尝试使用这种方法编译代码时,我很确定它会遇到冲突,因为它永远不会完成构建。可能会陷入各种混乱的循环,以为一堆坐标是相同的或类似的。

很抱歉,这个问题很简单,但是由于某种原因,我很困惑。我只是在寻找有关如何编写此哈希码的建议,以免冲突。

c# hash
3个回答
12
投票

如果这不是最好的方法,那可能是一个足够好的方法:

public override int GetHashCode()
{
   return string.Format("{0}-{1}-{2}-{3}", X, Y, Face, Shell).GetHashCode();
}

更新:看一下这篇文章:http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/


3
投票

基本上,在编写哈希码函数时,需要确保:

  • 您没有陈旧的哈希码(即,在生成哈希码后,对象的状态不应更改,这样,如果重新生成,则哈希码将发生变化)
  • 具有相等值的对象返回相同的哈希码
  • 同一对象总是返回相同的哈希码(如果未修改)-确定性

也很好,但不是必需的,如果:

  • 您的哈希码均匀分布在可能的值上(来源:Wikipedia

不需要需要确保不同的对象返回不同的哈希码。只是皱眉,因为它会降低Hashtables之类的性能(如果您有很多冲突)。

但是,如果您仍然希望哈希码函数返回唯一值,那么您想了解perfect hashing


0
投票

如果使用dotnetcore 2.1+,则可以使用HashCode struct的Combile方法,使用起来非常简单,而且效率很高。

© www.soinside.com 2019 - 2024. All rights reserved.