Как реализовать IEqualityComparer <PointF> с допуском

Этот вопрос подобен тому здесь.

Все мы знаем, каков PointF, не так ли? Это - структура данных:

public struct PointF
{
  public float X;
  public float Y;
}

Как реализовать IEqualityComparer с допуском? Скажем, мой Equals код похож на это

public const float Epsilon = 0.01; //say
public bool Equals(PointF pt1, PointF pt2)
{
   return Math.Abs(pt1.X-pt2.X)

Вопрос: Как реализовать корректное GetHashCode так, чтобы для словаря PointF, Я получу доступ к элементу правильно?

Я взламываю голову несколько дней, но все еще не могу найти удовлетворительное решение.

7
задан Community 23 May 2017 в 12:34
поделиться

2 ответа

Вместо того, чтобы определять толерантность на расстоянии, вы могли бы разместить точки в сетке.
Если две точки находятся в одной ячейке, они считаются равными и имеют тот же хэш-код.

public bool Equals(PointF pt1, PointF pt2)
{
   return GetCell(pt1.X) == GetCell(pt2.X)
       && GetCell(pt1.Y) == GetCell(pt2.Y);
}

public int GetHashCode(PointF pt)
{
   return GetCell(pt.X) ^ GetCell(pt.Y);
}

private static int GetCell(float f)
{
    return (int)(f / 10); // cell size is 10 pixels
}

Тезис: Не существует реализации равных и gethashCode , который соответствует вашим требованиям.

Доказательство: Рассмотрим следующие три точки, A, B и C:

Illustration

согласно вашим требованиям,

Equals(A, B) == true              // (i)
Equals(B, C) == true              // (ii)
Equals(A, C) == false             // (iii)
GetHashCode(A) == GetHashCode(B)  // (iv)
GetHashCode(B) == GetHashCode(C)  // (v)
GetHashCode(A) != GetHashCode(C)  // (vi)

, но из (IV) и (V) следует

GetHashCode(A) == GetHashCode(C)

и, таким образом,

Equals(A, C) == true

который противоречит (III) и (VI).

С равно и GethashCode не может вернуть разные значения для тех же аргументов, нет реализации, которая соответствует вашим требованиям. Q.E.D.

14
ответ дан 6 December 2019 в 14:04
поделиться

Не думаю, что это возможно, потому что можно иметь бесконечную последовательность значений, равных (в пределах допуска) предыдущему и следующему значению в последовательности, но не любое другое значение, и GetHashCode должен будет вернуть одинаковое значение для всех из них.

1
ответ дан 6 December 2019 в 14:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: