7
votes

Comment puis-je créer un hashcode pour une structure de données personnalisée?

J'ai fait une structure de données "coordonnées" personnalisée qui définit la position d'un objet selon un certain système.

Une coordonnée est définie comme suit: P>

private const int MULTIPLIER = 89;

[...]

int hashCode = 1;
hashCode = MULTIPLIER * hashCode + obj.X.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Y.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Face.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Shell.GetHashCode();
return hashCode;


4 commentaires

Il n'y a pas de problème du tout si les hashcodes entrent en collision. Il est préférable de ne pas obtenir de collisions, mais il n'est pas nécessaire (et que ce n'est pas possible, il n'est pas non plus possible).


msdn.microsoft.com/ FR-US / Bibliothèque / ... - "Les classes dérivées doivent remplacer GetHashCode avec une implémentation qui renvoie un code de hachage unique."


@Mattfenwick à cause du principe du pigeonhole, il n'existe pas de code de hachage unique pour la plupart des types. * Cet article est un peu inexact. Ils ont supprimé cette ligne dans des versions suivantes. * - int.GetHashCode () est probablement unique pour chaque numéro.


@Ilianpinzon - Bien, je suis content que ce soit faux parce que cela me confondait. Merci d'avoir nettoyé ça!


3 Réponses :


15
votes

Si ce n'est pas le meilleur moyen, cela peut être une approche suffisante: xxx

mise à jour: Jetez un coup d'œil à cet article: http://ericlippert.com / 2011/02/28 / Lignes directrices-et-Rules-for-gethashcode /


5 commentaires

Cela a l'air vraiment bien, merci. J'ai essayé de multiplier chaque composant de 100 000, 10000, 1000 et 1 avant de l'obtenir, mais cela est plus propre et extensible.


Eh bien, cela ne construit toujours pas ... Je garderai ce hashcode et ferai des tests unitaires pour voir si je fais quelque chose d'autre mal.


J'aurais dû dire "ça reste coincé", pas "ne construit pas". Il n'y a pas d'erreurs de compilateur. Le jeu est juste coincé dans une boucle qui utilise les codes de hachage.


Il s'avère que j'utilisais des exceptions lorsque j'aurais dû être plus intelligent avec le code et utilisé des booléens pour me dire si quelque chose a fonctionné ou non. Les exceptions ont ralentissaient l'initialisation du programme à une rampe. Le fait que ce ralentissement n'ait pas été apparu auparavant prouve que les choses avaient été erronées auparavant et que je n'avais pas réalisé. Merci pour ton aide; Mon colocataire m'a rappelé qu'une structure vaut mieux que de violer des hashcodes afin de comparer en valeur. Mais votre méthode fonctionnerait aussi et j'ai appris quelque chose!


Cette réponse est très inefficace si vous devez écrire un code évolutif, car vous devez d'abord convertir chaque int vers une chaîne, puis le calcul du hachage pour la chaîne entraîne des coûts supplémentaires. Pour Hashing Plusieurs champs Int efficacement, veuillez consulter ma réponse ici: Stackoverflow.com/a/34006336/1911540



3
votes

Fondamentalement, lorsque vous écrivez des fonctions HashCode, vous devez vous assurer que:

  • Vous n'avez pas de hashcodes stables (c'est-à-dire que l'état de l'objet ne doit pas changer une fois que le casque a été généré, de sorte que le crashcode changeait s'il est régénéré)
  • Les objets avec des valeurs égales renvoient les mêmes hashcodes
  • Le même objet renvoie toujours le même hashcode (s'il n'est pas modifié) - déterministe

    aussi, c'est génial, mais pas nécessaire, si:

    • Vos hadrcodes sont uniformément dispersés sur les valeurs possibles (source: Wikipedia )

      vous ne doit pas besoin de vous assurer que différents objets renvoient différents hachages. Ce n'est que mal vu que cela peut diminuer la performance des choses comme des hashtables (si vous avez beaucoup de collisions).

      Toutefois, si vous souhaitez toujours que votre fonction HashCode renvoie des valeurs uniques, vous souhaitez savoir sur hachage parfait .


0 commentaires

0
votes

Si vous utilisez dotnetcore 2.1+, vous pouvez utiliser HASHCODE 'S STRUCT'S COMBILE MÉTHODE, il est très facile à utiliser et à efficacité.


0 commentaires