2012-12-11 13 views
7

Próbuję wymyślić sposób nadpisania GetHashCode(), gdy wywołana z Vector2 []. Ten kod generuje unikatowe skróty dla obiektów, o których wiem, że są równe: przekazuję następującej klasie ten sam prostokąt i generowane są różne kody skrótu.Jak hash int [] w C#

public Shape(Rectangle r) 
     { 
      edges = new Vector2[4]; 
      edges[0] = new Vector2(0, 0); 
      edges[1] = new Vector2(r.Width, 0); 
      edges[2] = new Vector2(r.Width, r.Height); 
      edges[3] = new Vector2(0, r.Height); 
      Console.Write(edges.GetHashCode() + "\n"); 
      Position = new Vector2(r.X, r.Y);     
     } 

Tablica Vector2 jest po prostu wiązką elementów int. Jak mogę utworzyć unikatowy skrót dla listy intów?

+0

Może to powinno działać. Czy możesz zamieścić pełny przykład pokazujący dwa równe wektory, które generują różne kody skrótu? –

+1

Tablice nie zawierają kodu skrótu na podstawie zawartości tablicy .. więc ten kod nie będzie działał. Musisz uruchomić własny, lub jeśli korzystasz z .NET 4 użyj [IStructuralEquatable interface] (http://msdn.microsoft.com/en-us/library/system.collections.istructuralequatable.aspx). –

+0

@SimonWhitehead: Naprawdę? Co więc oznacza powrót [Vector2.GetHashCode] (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.gethashcode%28v=xnagamestudio.10%29.aspx)? –

Odpowiedz

4

Można użyć coś takiego:

public static int CombineHashCodes(params int[] hashCodes) 
{ 
    if (hashCodes == null) 
    { 
     throw new ArgumentNullException("hashCodes"); 
    } 

    if (hashCodes.Length == 0) 
    { 
     throw new IndexOutOfRangeException(); 
    } 

    if (hashCodes.Length == 1) 
    { 
     return hashCodes[0]; 
    } 

    var result = hashCodes[0]; 

    for (var i = 1; i < hashCodes.Length; i++) 
    { 
     result = CombineHashCodes(result, hashCodes[i]); 
    } 

    return result; 
} 

private static int CombineHashCodes(int h1, int h2) 
{ 
    return (h1 << 5) + h1^h2; 

    // another implementation 
    //unchecked 
    //{ 
    // var hash = 17; 

    // hash = hash * 23 + h1; 
    // hash = hash * 23 + h2; 

    // return hash; 
    //} 
} 
+0

Tak więc, pętle przechodzą przez tablicę dwa ints na raz, niosąc sumę, która jest nieco przesunięta o pięć w każdej iteracji, i zwiększa się o kolejny numer. Może nie rozumiem, jak działa zmiana biegów, ale czy nie spowoduje to masywnej, masywnej liczby? I powinienem zmienić rozmiar mojego stołu mieszającego na końcu? Bez względu na to, uważam to za pomocne. –

+2

@MaxKessler Nie. Używa działającego "skrótu beczkowego" (h1 jest mieszany z h2), więc nigdy nie przekracza rozmiaru int i * bity przesunięte poza koniec są zrzucane *. Pamiętaj, że, ogólnie, * hashe nie są (i nie mogą być) unikalne *; muszą być stabilne i, mam nadzieję, dobrze rozmieszczone. –

+0

Zrozumiano! Zmieniłem swój kod tak, aby kolizja nie była używana jako sposób na stwierdzenie, czy dwa obiekty są sobie równe: Zrobiłem trochę badań i przejąłem metodę równości na moich obiektach. Dziękuję Ci bardzo! –