【发布时间】:2011-12-17 00:22:37
【问题描述】:
我已经制作了一个自定义的“坐标”数据结构,它根据某个系统定义对象的位置。
坐标定义如下:
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 Face(0 到 5)、一个 int X、int Y 和 int Shell。 X、Y 和 Shell 都绑定在 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;
关闭我在谷歌搜索时发现的东西。但是当我尝试用这种方法编译代码时,我很确定它会遇到冲突,因为它永远不会完成构建。可能会陷入各种混乱的循环,认为一堆坐标是相同的或类似的。
对不起,这个问题相当初级,但出于某种原因,我很难过。我只是在寻找有关如何编写此哈希码以使其不会发生冲突的建议。
【问题讨论】:
-
hashcode 碰撞完全没有问题。最好不要发生碰撞,但这不是必需的(在数学上也是不可能的)。
-
msdn.microsoft.com/en-us/library/… -- "派生类必须使用返回唯一哈希码的实现覆盖 GetHashCode。"
-
@MattFenwick 由于鸽巢原理,大多数类型都没有唯一的哈希码。* 那篇文章有点不准确。他们在后续版本中删除了该行。 *-
int.GetHashCode()可能对于每个数字都是唯一的。 -
@IlianPinzon -- 很好,我很高兴这是错误的,因为它让我感到困惑。感谢您清除它!