문제

이 질문은 비슷합니다 여기 하나.

우리 모두는 무엇을 알고 있습니다 Pointf 우리는 그렇지 않습니까? 이것은 데이터 구조입니다.

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

구현 방법 IEqualityComparer<PointF> 관용으로? 내 말하자 Equals 코드는 다음과 같습니다

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

질문 : 올바른 구현 방법 GetHashCode 그래서 사전의 경우 PointF, 요소에 올바르게 액세스할까요?

나는 며칠 동안 머리를 부수지만 여전히 만족스러운 해결책을 찾을 수 없습니다.

도움이 되었습니까?

해결책

거리별로 공차를 정의하는 대신 점을 그리드에 배치 할 수 있습니다.
두 지점이 같은 셀에있는 경우 동일하게 간주되며 동일한 해시 코드가 있습니다.

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
}

명제: 구현이 없습니다 Equals 그리고 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).

부터 Equals 그리고 GetHashCode 동일한 인수에 대해 다른 값을 반환 할 수 없으므로 요구 사항을 충족시키는 구현이 없습니다.Qed

다른 팁

나는 당신이 순서에서 이전 및 다음 값과 동일하지만 다른 값과 다른 값과 동일하는 무한한 값 순서를 가질 수 있기 때문에 가능하지 않다고 생각합니다. GetHashCode 그들 모두에 대해 동일한 가치를 반환해야합니다.

글쎄, 그리드를 기반으로 한 대답은 좋지만 때로는 그리드 셀에 있지 않더라도 가까운 포인트를 그룹화해야합니다. 내 접근 방식은 그룹화를 사용하여 이것을 구현하는 것입니다. 두 점이 가까이 있거나 연결하는 일련의 가까운 지점이있는 경우 두 점이 동일한 그룹에 있습니다. 이 의미론은 적절한 상태로 수행 할 수 없습니다 IEqualityComparer, 그룹을 생산하기 전에 모든 항목을 미리 알아야하기 때문입니다. 그래서 간단한 LINQ 스타일의 연산자를했습니다 GroupByCluster, 기본적으로 이것을 달성합니다.

코드는 다음과 같습니다. http://ideone.com/8l0lh. 내 VS 2010에서 컴파일하지만 Mono에서 컴파일하지 못합니다. HashSet<> 암시 적으로 변환 될 수 없습니다 IEnumerable<> (왜?).

접근 방식은 일반적이므로 매우 효율적이지 않습니다. 입력 크기의 2 차입니다. 콘크리트 유형의 경우 더 효율적으로 만들 수 있습니다. 예를 들어 T = Double의 경우 입력 배열을 정렬하고 가질 수 있습니다. O(n log n) 성능. 유사하지만 더 복잡한 트릭은 2D 포인트에도 적용됩니다.


주목하십시오 : 당신의 초기 제안은 IEqualityComparer, 당신의 "근사 평등"은 전이적이지 않기 때문에 (그러나 평등은 IEqualityComparer 그렇게되어야합니다).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top