2013-07-26 3 views
1

문자열 배열 (약 2000)이 있는데, IEnumerable.GroupBy을 사용하여 동일한 문자열을 그룹화합니다. 같은 많은 해시 충돌이 있다고하지만문자열에 대한 GroupBy (해시 코드 충돌)

문제는 "신비""잘". 이것은 아마도 GroupBy가 int가 너무 작거나 (또는 ​​String 클래스의 GetHashCode 함수가 제대로 구현되지 않은) 012H를 반환하는 GetHashCode ()를 으로 사용했기 때문일 수 있습니다.

나는 당신이 오버라이드 (override) GetHashCode 기능을 구현하려고하거나 사용자 정의 을 정의 IEqualityComparer을하고 다른 해시 코드를 사용할 수 있습니다 생각하지만, 직접 또는 다르게 비교할 수있는 방법이 없다? 나는 그것이 더 오래 걸릴 것이라는 것을 알고있다, 그러나 소량에 그것은 받아 들여진다. 어떻게 해결할 수 있을까요?

+0

GetHashCode는 * equals와 * 작동합니다. 해시 기반지도를 구현하는 데 도움을주고 * 평등하지는 않음을 보여줄 수 있지만 평등성을 증명할 수는 없습니다. 표준 String.GetHashCode는이 목적을 위해 충분히 잘 작동해야합니다 ("잘 구현되지 않았습니다"를 지원하는 링크를 제공하십시오) : 정수는 2000 비트 이상의 값을 나타낼 수 있으며 가끔 충돌은 중요하지 않습니다. String을 하위 클래스화할 수는 없지만 IEqualityComparer를 사용할 수는 있습니다. 이유는 모르지만. – user2246674

+0

또한 "신비하게".GetHashCode() == "well".GetHashCode()에 대한 어설 션은 .NET 4.5에서 잘못되었습니다. 다른 버전에 대해서는 모르겠지만 .NET에 String이 있으면 매우 놀랍습니다. 암시 적으로 "절대적으로 심했다"는 해시 코드 생성. (그러나 해시 알고리즘은 충돌 공격의 대상이 될 수 있음을 명심하십시오. 이것은 동일한 해시 코드로 인한 무작위 입력과는 많이 다릅니다. 이러한 공격과 실제로 "중복 해시"는 성능에 영향을 미칠 수 있지만 정확함에 영향을 미치지 않습니다.) – user2246674

+0

네, 죄송합니다. 각 그룹에서 모든 문자열을 인쇄했습니다. 내가 쓴 문자열은 여러 줄을 포함 할 수 있기 때문에 일치하는 것으로 보입니다. 잘못된 디버깅 일 것입니다. 미안합니다. 그에 대한! – hl3mukkel

답변

2

문자열의 GroupBy는 동일한 해시 코드를 가지고 있는지 여부에 관계없이 동일한 문자열 만 그룹화합니다. GroupBy가 해시 테이블을 사용하기 때문에 동일한 해시 코드를 사용하는 여러 문자열이 성능을 약간 저하시킬 수 있지만 올바른 답을 제공합니다.

는 자신이 증명 GROUPBY조차 끔찍한 해시 기능이있는 사용자 정의 IEqualityComparer으로 위대한 작품을 참고 : 또한

void Main() 
{ 
    var groups = new[] { "a", "a", "b", "b", "c", "c" }.GroupBy(s => s, new BadComparer()) 
     .Select(g => string.Join(",", g)) 
     .ToArray(); 
    Console.WriteLine(string.Join(Environment.NewLine, groups)); 
    // this prints: 
    // a,a 
    // b,b 
    // c,c  
} 

public class BadComparer : IEqualityComparer<string> { 
    public bool Equals(string a, string b) { return a == b; } 
    public int GetHashCode(string s) { return 0; } 
} 

주는 캐릭터 자체보다는 해시가 그룹에 중요하다고를 코드 :

myStrings.GroupBy(s => s) // works

myStrings.GroupBy(s => s.GetHashCode()) // doesn't work

+0

흠. 이상한데, GroupBy가 나에게 잘못된 그룹을 제공하는 증거가 있습니다. 단 하나의 배열에서 단어를 테스트하면 일치하지 않을 것입니다. – hl3mukkel

+0

이유를 모르겠습니다. 어쨌든, 감사합니다! – hl3mukkel