2016-09-29 2 views
1

C#를 GetHashCode 구현

public override int GetHashCode() 
{ 
    return Word.GetHashCode(); 
} 

는 고유성에 관한

public override int GetHashCode() 
{ 
    return (int) Word.GetHashCode() * 7; 
} 

에 정말 동일합니까?

Word

유형이다 String

편집 : 내가 어느 프로그램, 옵션 1 또는 2에 구현하는 것이 좋습니다, 말을 잊으 셨나요?

+3

해시 코드가 필요 없으며 고유 할 수도 있으므로 두 가지 구현이 고유하지 않은 해시 코드를 생성한다는 의미에서 질문에 대한 대답은 "예"입니다. – dasblinkenlight

+5

'Word.GetHashCode()와의 충돌은 여전히 ​​7을 곱한 후에 충돌 할 것입니다. 또한 캐스트는 무의미합니다. – juharr

+0

'world.GetHashCode()'가 worldA와 worldB에 대해 6을 생성하면 juharr의 주석을 확장 한 다음'World.GetHashCode() * 7'는 worldA와 worldB 모두에 대해 42를 생성합니다. –

답변

2

Word.GetHashCode() 구현에서 충돌이 발생하면 (int) Word.GetHashCode() * 7 구현에서 충돌이 발생합니다. 동일한 숫자를 곱하면 동일한 결과가 산출되므로 분명합니다.

더 흥미로운 질문은 첫 번째 구현의 비 충돌 해시 코드가 두 번째 구현 내에서 충돌을 일으키는 경우입니다. int7의 범위는 서로 소숫자이기 때문에 대답은 "아니오"입니다. 따라서 곱셈은 오버플로를 제거한 후에 고유 한 매핑을 생성합니다.

const int Max = 1<<16; 
var count = new int[Max]; 
for (int i = 0 ; i != Max ; i++) { 
    count[(i * 7) & (Max-1)]++; 
} 
var notOne = 0; 
for (int i = 0 ; i != Max ; i++) { 
    if (count[i] != 1) { 
     notOne++; 
    } 
} 
Console.WriteLine("Count of duplicate mappings found: {0}", notOne); 

이 프로그램은, i, 해시 코드 값을 매핑 모듈 2 167 * i에, 각 있는지 확인합니다 :

당신은 어떻게되는지 2 바이트 해시 코드와 함께 작은 테스트를 실행할 수 있습니다 범위의 숫자는 정확히 한 번만 생성됩니다.

Demo.

당신이 짝수로 7를 교체 할 경우

Count of duplicate mappings found: 0 

는, 결과는 매우 다를 것입니다. 이제 원본 세트의 여러 해시 코드가 대상 세트의 단일 해시 코드에 매핑됩니다. 짝수로 곱하면 항상 최하위 비트가 0이된다는 것을 기억하면 직관적으로 이것을 이해할 수 있습니다. 따라서 짝수를 2로 나눌 수있는 횟수에 따라 일부 정보가 손실됩니다.

어느 쪽이 더 낫습니까?

차이는 없습니다.

참고 : 위의 내용은 정수 오버플로를 무시하고 있다고 가정합니다.

+0

예, 나는 목적 넘은 숫자를 말하는 걸 잊었습니다. 어느 쪽이 더 낫지? 옵션 A 또는 B? –

+0

이렇게하면 차이가 없으므로 간단한 옵션을 사용하십시오. – stuartd

+0

@HendrikBreezy .NET은 프라임 버킷 카운트를 사용하는 데주의를 기울이기 때문에 차이가 없습니다. – dasblinkenlight

0

unchecked 컨텍스트에서 코드를 실행하지 않으므로 후자는 오버플로가 발생할 때마다 예외를 throw하므로 합리적으로 가능성이 높습니다 (해시 범위의 6/7이 발생하므로 일반적으로 균등하게 분산됩니다 해시 코드는 ~ 6/7의 예외가 발생할 가능성이 있습니다.

+0

https://msdn.microsoft.com/en-gb/library/a569z7k8.aspx에서 "비정규 조건을 포함하는 표현식은 컴파일 타임과 실행 시간에 기본적으로 선택 취소됩니다." 명시 적으로 확인하지 않으면 선택을 취소 하시겠습니까? 나는 내가 체크/체크되지 않은 것에 대해 걱정할 필요가있는 곳에서 실제로 놀지 않았다고 인정할 것이다. 그래서 나는 쉽게 틀릴 수도있다. – Chris

+1

@Chris C# 컴파일러와 VS 기본값은 선택하지 않았다. –