diff --git a/analyseur.c b/analyseur.c index b6471a2..0118d97 100644 --- a/analyseur.c +++ b/analyseur.c @@ -235,24 +235,34 @@ int est_mot_vide(const char *mot) return 0; } -int chercher_mot(Entree *table, int nb_entrees, const char *mot) +/* Table de hachage à adressage ouvert : chaque case contient l'indice + 1 + * d'un mot de la table, ou 0 si elle est vide. Sa taille est une puissance + * de 2 nettement supérieure à MAX_MOTS_UNIQUES pour garder des sondages courts. */ +#define TAILLE_HACHAGE 32768 + +static int index_mots[TAILLE_HACHAGE]; + +unsigned long empreinte(const char *s); + +/* Renvoie la case de index_mots qui contient mot, ou la case vide où l'ajouter. */ +unsigned long chercher_mot(const Entree *table, const char *mot) { - for (int i = 0; i < nb_entrees; i++) { - if (egales(table[i].mot, mot)) - return i; - } - return -1; + unsigned long h = empreinte(mot) & (TAILLE_HACHAGE - 1); + while (index_mots[h] != 0 && !egales(table[index_mots[h] - 1].mot, mot)) + h = (h + 1) & (TAILLE_HACHAGE - 1); + return h; } void compter_mot(Entree *table, int *nb_entrees, const char *mot) { - int indice = chercher_mot(table, *nb_entrees, mot); - if (indice >= 0) { - table[indice].occurrences++; + unsigned long h = chercher_mot(table, mot); + if (index_mots[h] != 0) { + table[index_mots[h] - 1].occurrences++; } else { copier(table[*nb_entrees].mot, mot); table[*nb_entrees].occurrences = 1; (*nb_entrees)++; + index_mots[h] = *nb_entrees; } }