web-dev-qa-db-fra.com

Hash: Comment ça marche en interne?

Cela peut sembler une question très vague dès le départ, mais ce n'est pas le cas. J'ai parcouru Fonction de hachage description sur le wiki mais ce n'est pas très utile à comprendre.

Je cherche des réponses simples pour des sujets plutôt complexes comme le hachage. Voici mes questions:

  1. Qu'entendons-nous par hachage? Comment ça marche en interne?
  2. Quel algorithme suit-il?
  3. Quelle est la différence entre HashMap, HashTable et HashList?
  4. Qu'entendons-nous par "complexité à temps constant" et pourquoi une implémentation différente du hachage donne-t-elle un fonctionnement à temps constant?
  5. Enfin, pourquoi dans la plupart des questions d'entrevue Hash et LinkedList sont posées, y a-t-il une logique spécifique pour cela en testant les connaissances de la personne interrogée?

Je sais que ma liste de questions est grande mais j'apprécierais vraiment si je peux obtenir des réponses claires à ces questions car je veux vraiment comprendre le sujet.

49
Rachel
  1. Ici est une bonne explication sur le hachage. Par exemple, vous souhaitez stocker la chaîne "Rachel", vous appliquez une fonction de hachage à cette chaîne pour obtenir un emplacement de mémoire. myHashFunction(key: "Rachel" value: "Rachel") --> 10. La fonction peut renvoyer 10 pour l'entrée "Rachel" donc en supposant que vous avez un tableau de taille 100 vous stockez "Rachel" à l'index 10. Si vous voulez récupérer cet élément, vous appelez simplement GetmyHashFunction("Rachel") et il retournera 10. Notez que pour cet exemple, la clé est "Rachel" et la valeur est "Rachel" mais vous pouvez utiliser une autre valeur pour cette clé, par exemple la date de naissance ou un objet. Votre fonction de hachage peut renvoyer le même emplacement de mémoire pour deux entrées différentes, dans ce cas, vous aurez une collision si vous implémentez votre propre table de hachage, vous devez en prendre soin en utilisant peut-être une liste chaînée ou d'autres techniques.

  2. Ici sont quelques fonctions de hachage courantes utilisées. Une bonne fonction de hachage vérifie que: chaque clé est également susceptible de hacher vers l'un des n emplacements de mémoire indépendamment de l'endroit où toute autre clé a haché. L'une des méthodes est appelée méthode de division. Nous mappons une clé k dans l'un des n emplacements en prenant le reste de k divisé par n. h(k) = k mod n. Par exemple, si la taille de votre tableau est n = 100 Et votre clé est un entier k = 15 Alors h(k) = 10.

  3. Hashtable est synchronisé et Hashmap ne l'est pas. Hashmap autorise les valeurs nulles comme clé, mais pas Hashtable.

  4. Le but d'une table de hachage est d'avoir O(c) complexité temporelle constante lors de l'ajout et de l'obtention des éléments. Dans une liste chaînée de taille N si vous voulez obtenir le dernier élément, vous devez parcourez toute la liste jusqu'à ce que vous l'obteniez pour que la complexité soit O (N). Avec une table de hachage si vous voulez récupérer un élément, il vous suffit de passer la clé et la fonction de hachage vous renverra l'élément souhaité. Si la fonction de hachage est bien implémenté il sera en temps constant O(c) Cela signifie que vous n'avez pas à parcourir tous les éléments stockés dans la table de hachage. Vous obtiendrez l'élément "instantanément".

  5. Bien entendu, un informaticien programmeur/développeur doit connaître les structures et la complexité des données =)

28
Enrique
  1. Le hachage signifie générer un nombre (espérons-le) unique qui représente une valeur.
  2. Différents types de valeurs (Integer, String, etc.) utilisent différents algorithmes pour calculer un code de hachage.
  3. HashMap et HashTable sont maps; il s'agit d'une collection de clés non valides, chacune étant associée à une valeur.
    Java n'a pas de classe HashList. Un hachageEnsemble est un ensemble de valeurs uniques.
  4. Obtenir un élément à partir d'une table de hachage est un temps constant en ce qui concerne la taille de la table.
    Le calcul d'un hachage n'est pas nécessairement à temps constant en ce qui concerne la valeur hachée.
    Par exemple, le calcul du hachage d'une chaîne implique l'itération de la chaîne et n'est pas à temps constant en ce qui concerne la taille de la chaîne.
  5. Ce sont des choses que les gens devraient savoir.
9
SLaks

Je vais essayer de donner des explications simples sur le hachage et son objectif.

Considérons d'abord une liste simple. Chaque opération (insérer, rechercher, supprimer) sur une telle liste aurait une complexité O(n), ce qui signifie que vous devez analyser la liste entière (ou la moitié, en moyenne) pour effectuer une telle une opération.

Le hachage est un moyen très simple et efficace de l'accélérer: considérez que nous avons divisé la liste entière en un ensemble de petites listes. Les éléments d'une telle petite liste auraient quelque chose en commun, et ce quelque chose peut être déduit de la clé. Par exemple, en ayant une liste de noms, nous pourrions utiliser la première lettre comme la qualité qui choisira dans quelle petite liste regarder. De cette façon, en partitionnant les données par la première lettre de la clé, nous avons obtenu un hachage simple, qui serait capable de diviser la liste entière en ~ 30 listes plus petites, de sorte que chaque opération prendrait O (n)/30 fois .

Cependant, nous avons pu noter que les résultats ne sont pas si parfaits. Premièrement, il n'y en a que 30, et nous ne pouvons pas le changer. Deuxièmement, certaines lettres sont utilisées plus souvent que d'autres, de sorte que l'ensemble avec Y ou Z sera beaucoup plus petit que l'ensemble avec A. Pour de meilleurs résultats, il est préférable de trouver un moyen de partitionner les éléments en ensembles de même taille. Comment pourrions-nous résoudre cela? C'est là que vous utilisez les fonctions de hachage. C'est une telle fonction qui est capable de créer un nombre arbitraire de partitions avec à peu près le même nombre d'éléments dans chacune. Dans notre exemple avec des noms, nous pourrions utiliser quelque chose comme

int hash(const char* str){
    int rez = 0;
    for (int i = 0; i < strlen(str); i++)
        rez = rez * 37 + str[i];
    return rez % NUMBER_OF_PARTITIONS;
};

Cela assurerait une distribution assez uniforme et un nombre configurable d'ensembles (également appelés compartiments).

5
ruslik
  1. Le hachage transforme une entité donnée (en Java - un objet) en un certain nombre (ou séquence). La fonction de hachage n'est pas réversible - c'est-à-dire que vous ne pouvez pas obtenir l'objet d'origine à partir du hachage En interne, il est implémenté (pour Java.lang.Object En obtenant une adresse mémoire par la JVM.

  2. L'adresse JVM est un détail sans importance. Chaque classe peut remplacer la méthode hashCode() par son propre algorithme. Modren Java Les IDE permettent de générer de bonnes méthodes hashCode.

  3. Hashtable et hashmap sont la même chose. Ce sont des paires clé-valeur, où les clés sont hachées. Les listes de hachage et les hashsets ne stockent pas de valeurs - uniquement des clés.

  4. Le temps constant signifie que peu importe le nombre d'entrées dans la table de hachage (ou toute autre collection), le nombre d'opérations nécessaires pour trouver un objet donné par sa clé est constant. Soit - 1, soit près de 1

  5. Il s'agit de matériel informatique de base, et on suppose que tout le monde le connaît. Je pense que Google a précisé que la table de hachage est la structure de données la plus importante en informatique.

5
Bozho

Qu'entendons-nous par hachage, comment cela fonctionne-t-il en interne?

Le hachage est la transformation d'une chaîne ou d'une valeur de longueur fixe plus courte qui représente la chaîne d'origine. Ce n'est pas l'indexation. Le cœur du hachage est la table de hachage. Il contient un tableau d'éléments. Les tables de hachage contiennent un index de la clé de l'élément de données et utilisent cet index pour placer les données dans le tableau.

Quel algorithme suit-il?

En termes simples, la plupart des algorithmes de hachage fonctionnent sur la logique "index = f (key, arrayLength)"

Enfin, pourquoi dans la plupart des questions d'entrevue Hash et LinkedList sont posées, y a-t-il une logique spécifique pour cela en testant les connaissances de la personne interrogée?

C'est à quel point vous êtes bon en raisonnement logique. C'est la structure de données la plus importante que tous les programmeurs connaissent.

0
user517400