Optimiser la recherche des mots avec une table de hachage

This commit is contained in:
2026-10-07 10:36:55 +02:00
parent 6165b37b51
commit 2db740d742
+32 -6
View File
@@ -14,7 +14,7 @@
* L'empreinte affichée à la fin doit rester IDENTIQUE après optimisation : * L'empreinte affichée à la fin doit rester IDENTIQUE après optimisation :
* elle prouve que le résultat du programme n'a pas changé. * elle prouve que le résultat du programme n'a pas changé.
* *
* Compilation : gcc -O0 -g -pg analyseur.c -o analyseur * Compilation : gcc -O0 -pg analyseur.c -o analyseur
* Exécution : ./analyseur * Exécution : ./analyseur
* Profil : gprof ./analyseur gmon.out > profil.txt * Profil : gprof ./analyseur gmon.out > profil.txt
*/ */
@@ -235,23 +235,49 @@ int est_mot_vide(const char *mot)
return 0; return 0;
} }
int chercher_mot(Entree *table, int nb_entrees, const char *mot) /* Indices + 1 : zéro représente une case libre. Charge < 31 %. */
#define CAPACITE_INDEX 65536
static int index_mots[CAPACITE_INDEX];
unsigned long hacher_mot(const char *mot)
{ {
for (int i = 0; i < nb_entrees; i++) { unsigned long h = 5381;
if (egales(table[i].mot, mot)) for (int i = 0; mot[i] != '\0'; i++)
return i; h = h * 33 + (unsigned char)mot[i];
return h;
}
int chercher_mot(Entree *table, const char *mot, unsigned long *case_libre)
{
unsigned long position = hacher_mot(mot) % CAPACITE_INDEX;
while (index_mots[position] != 0) {
int indice = index_mots[position] - 1;
if (egales(table[indice].mot, mot))
return indice;
position = (position + 1) % CAPACITE_INDEX;
} }
*case_libre = position;
return -1; return -1;
} }
void compter_mot(Entree *table, int *nb_entrees, const char *mot) void compter_mot(Entree *table, int *nb_entrees, const char *mot)
{ {
int indice = chercher_mot(table, *nb_entrees, mot); /* Réinitialisation possible pour un nouveau comptage. */
if (*nb_entrees == 0)
for (int i = 0; i < CAPACITE_INDEX; i++)
index_mots[i] = 0;
unsigned long position;
int indice = chercher_mot(table, mot, &position);
if (indice >= 0) { if (indice >= 0) {
table[indice].occurrences++; table[indice].occurrences++;
} else { } else {
if (*nb_entrees == MAX_MOTS_UNIQUES) {
fputs("Trop de mots distincts\n", stderr);
exit(EXIT_FAILURE);
}
copier(table[*nb_entrees].mot, mot); copier(table[*nb_entrees].mot, mot);
table[*nb_entrees].occurrences = 1; table[*nb_entrees].occurrences = 1;
index_mots[position] = *nb_entrees + 1;
(*nb_entrees)++; (*nb_entrees)++;
} }
} }