abe*_*nci 9 .net c# collections visual-studio
我正在尝试跳过以下值列表的重复项。我试图实现的结果是-112.94487230674, -49.47838592529, -89.9999574979198,我正在使用HashSet类。我已经实现了下面的IEqualityComparer但它不起作用。
我究竟做错了什么?
class HeightEqualityComparer : IEqualityComparer<double>
{
public bool Equals(double a, double b)
{
return a - b < 1e-3;
}
public int GetHashCode(double value)
{
return value.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
以下是值列表:
[0] -112.94487230674 double
[1] -112.94487230674001 double
[2] -49.478385925290006 double
[3] -49.47838592529 double
[4] -49.478385925289992 double
[5] -89.9999574979198 double
[6] -89.99995749791978 double
[7] -49.478385925289984 double
[8] -89.999957497919809 double
[9] -49.478385925290013 double
Run Code Online (Sandbox Code Playgroud)
那么,目前的实施 Equals
return a - b < 1e-3;
Run Code Online (Sandbox Code Playgroud)
是不正确的。Equals必须是
Equals(a, a) == true;Equals(a, b) == Equals(b, a);Equals(a, b) && Equals(b, c)导致Equals(a, c);条件2和3在当前实施中不成立。在Math.Abs;的帮助下很容易修复第二个条件;第三个是真正的困难:对于任意正数tolerance
(1e-3在你的情况下),我们有
a == a + tolerance == a + 2 * tolerance == ... == a + n * tolerance
Run Code Online (Sandbox Code Playgroud)
意思是
a == a + n * tolerance
Run Code Online (Sandbox Code Playgroud)
对于任意大 n; 因此a == b对于所有a和b(所有数字都相等)。
作为部分(但有效)的解决方案,您可以尝试四舍五入这些值:
class HeightEqualityComparer : IEqualityComparer<double>
{
public bool Equals(double a, double b)
{
return Math.Round(a, 3) == Math.Round(b, 3);
}
public int GetHashCode(double value)
{
return Math.Round(value, 3).GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
注意,我们必须改变 GetHashCode