From a50565094c96147a043354dc84cb626c93dd619b Mon Sep 17 00:00:00 2001 From: Orestis <orestis.malaspinas@pm.me> Date: Tue, 11 Jan 2022 10:20:27 +0100 Subject: [PATCH] added example of hash functions --- slides/cours_13.md | 169 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 3 deletions(-) diff --git a/slides/cours_13.md b/slides/cours_13.md index 0c6990f..48b9498 100644 --- a/slides/cours_13.md +++ b/slides/cours_13.md @@ -17,8 +17,6 @@ patat: # Tableau vs Table -Structures permettant de stocker une collection d'éléments du même type. - ## Tableau * Chaque élément (ou valeur) est lié à un indice (la case du tableau). @@ -103,7 +101,9 @@ Efficacité dépend de différents paramètres: . . . ```C -bool sequential(int n, key_value_t table[n], key_t key, value_t *value) { +bool sequential_get(int n, key_value_t table[n], key_t key, + value_t *value) +{ int pos = n - 1; while (pos >= 0) { if (key == table[pos].key) { @@ -138,6 +138,8 @@ Poster le résultat sur matrix. # Consultation dichotomique (`binary_get`) +\footnotesize + ## Implémentation? Une idée? . . . @@ -164,6 +166,8 @@ bool binary_get1(int n, value_key_t table[n], key_t key, value_t *value) { # Consultation dichotomique (`binary_get`) +\footnotesize + ## Autre implémentation ```C @@ -189,4 +193,163 @@ bool binary_get2(int n, key_value_t table[n], key_t key, value_t *value) { ## Quelle est la différence avec le code précédent? +# Transformation de clé (hashing) + +## Problématique: Numéro AVS (13 chiffres) + +* Format: 106.3123.8492.13 + + ``` + Numéro AVS | Nom + 0000000000000 | ------- + ... | ... + 1063123849213 | Paul + ... | ... + 3066713878328 | Orestis + ... | ... + 9999999999999 | ------- + ``` + +## Quelle est la clé? Quelle est la valeur? + +. . . + +* Clé: Numéro AVS, Valeur: Nom. + +## Nombre de clés? Nombre de citoyens? Rapport? + +. . . + +* $10^{13}$ clés, $10^8$ citoyens, $10^{-5}$ ($10^{-3}\%$ de la table est + occupée) $\Rightarrow$ *inefficace*. +* Pire: $10^{13}$ entrées ne rentre pas dans la mémoire d'un + ordinateur. + +# Transformation de clé (hashing) + +## Problématique 2: Identificateurs d'un programme + +* Format: 8 caractères (simplification) + + ``` + Identificateur | Adresse + aaaaaaaa | ------- + ... | ... + resultat | 3aeff + compteur | 4fedc + ... | ... + zzzzzzzz | ------- + ``` + +## Quelle est la clé? Quelle est la valeur? + +. . . + +* Clé: Identificateur, Valeur: Adresse. + +## Nombre de clés? Nombre d'identificateur d'un programme? Rapport? + +. . . + +* $26^{8}\sim 2\cdot 10^{11}$ clés, $2000$ identificateurs, $10^{-8}$ ($10^{-6}\%$ de la table est + occupée) $\Rightarrow$ *un peu inefficace*. + +# Fonctions de transformation de clé (hash functions) + +* La table est représentée avec un tableau. +* La taille du tableau est beaucoup plus petit que le nombre de clés. +* On produit un indice du tableau à partir d'une clé: +$$ +h(key) = n,\quad n\in\mathbb{N}. +$$ +En français: on transforme `key` en nombre entier qui sera l'indice dans le +tableau correspondant à `key`. + +## La fonction de hash + +* La taille du domaine des clés est beaucoup plus grand que le domaine des + indices. +* Plusieurs indices peuvent correspondre à la **même clé**: + * Il faut traiter les **collisions**. +* L'ensemble des indices doit être plus petit ou égal à la taille de la table. + +## Une bonne fonction de hash + +* Distribue uniformément les clés sur l'ensemble des indices. + +# Fonctions de transformation de clés: exemples + +## Méthode par troncature + +\begin{align*} +&h: [0,9999]\rightarrow [0,9]\\ +&h(key)=\mbox{troisième chiffre du nombre.} +\end{align*} + +``` +Key | Index +0003 | 0 +1123 | 2 \ +1234 | 3 |-> collision. +1224 | 2 / +1264 | 6 +``` + +## Quelle est la taille de la table? + +. . . + +C'est bien dix oui. + +# Fonctions de transformation de clés: exemples + +## Méthode par découpage + +Taille de l'index: 3 chiffres. + +``` +key = 321 991 24 -> 321 + 991 + + 24 + ---- + 1336 -> index = 336 +``` + +## Devinez l'algorithme? + +. . . + +On part de la gauche: + +1. On découpe la clé en tranche de longueur égale à celle de l'index. +2. On somme les nombres obtenus. +3. On tronque à la longueur de l'index. + +# Fonctions de transformation de clés: exemples + +## Méthode multiplicative + +Taille de l'index: 2 chiffres. + +``` +key = 5486 -> key^2 = 30096196 -> index = 96 +``` + +On prend le carré de la clé et on garde les chiffres du milieu du résultat. + +# Fonctions de transformation de clés: exemples + +## Méthode par division modulo + +Taille de l'index: `N` chiffres. + +``` +h(key) = key % N. +``` + +## Quelle doit être la taille de la table? + +. . . + +Oui comme vous le pensiez au moins `N`. -- GitLab