| 238 | == Les fonctions de bases de la tables de hachage == |
| 239 | |
| 240 | '''hte.h''' |
| 241 | {{{ |
| 242 | 1 #ifndef _HTE_H_ |
| 243 | 2 #define _HTE_H_ |
| 244 | 3 |
| 245 | 4 #include <stdlib.h> |
| 246 | 5 |
| 247 | 6 |
| 248 | 7 /* |
| 249 | 8 * Les deux structures ci-dessous ne sont pas définies ici |
| 250 | 9 * elles seront redéfinies dans chaque fichier |
| 251 | 10 */ |
| 252 | 11 typedef struct hte_item_s hte_item_t; |
| 253 | 12 typedef struct hte_data_s hte_data_t; |
| 254 | 13 |
| 255 | 14 |
| 256 | 15 /* |
| 257 | 16 * structure définissant la table de hachage |
| 258 | 17 * On y trouve le nombre de liste de liste et |
| 259 | 18 * un pointeur vers le tableau de liste |
| 260 | 19 */ |
| 261 | 20 typedef struct hte_root_s |
| 262 | 21 { |
| 263 | 22 size_t NB_LIST; /* nombre de liste d'ITEM du dictionnaire */ |
| 264 | 23 hte_item_t **LIST; /* pointeur sur un tableau de liste d'ITEM */ |
| 265 | 24 } hte_root_t; |
| 266 | 25 |
| 267 | 26 |
| 268 | 27 /* |
| 269 | 28 * Calcul de l'index de hachage de Donald Knuth |
| 270 | 29 * Elle produit un nombre entier à partir d'une chaine de caractères. |
| 271 | 30 */ |
| 272 | 31 extern unsigned hte_hash (char *key); |
| 273 | 32 |
| 274 | 33 |
| 275 | 34 /* |
| 276 | 35 * hte_create fabrique une table de hachage vide |
| 277 | 36 * parametres: |
| 278 | 37 * nb_item = nombre d'item maximum prévu dans la table de hachage |
| 279 | 38 */ |
| 280 | 39 extern hte_root_t *hte_create (size_t nb_item); |
| 281 | 40 |
| 282 | 41 |
| 283 | 42 /* ------------------------------------------------------------------------ */ |
| 284 | 43 |
| 285 | 44 |
| 286 | 45 /* |
| 287 | 46 * hte_add ajoute l'item (key,data) |
| 288 | 47 * parametres: |
| 289 | 48 * root = pointeur sur la table de hachage |
| 290 | 49 * key = pointeur sur une chaine de caractères (la clé) |
| 291 | 50 * data = donnée associée à key |
| 292 | 51 * comportement: |
| 293 | 52 * La clé key passée en parametre est comparée à celles présentes dans |
| 294 | 53 * la table. Si la clé n'est pas trouvée alors un nouvel item est créé |
| 295 | 54 * avec le couple (key,data). La clé key est en fait duppliquée. |
| 296 | 55 * Si la clé est trouvée, le champ DATA de l'item présent dans la |
| 297 | 56 * table est remplacé par le paramètre data de la fonction. |
| 298 | 57 * retour: |
| 299 | 58 * Si l'item n'a pu etre créé faute d'espace, on sort du programme. |
| 300 | 59 */ |
| 301 | 60 extern void hte_add (hte_root_t * root, char *key, hte_data_t * data); |
| 302 | 61 |
| 303 | 62 |
| 304 | 63 /* |
| 305 | 64 * hte_get recherche item, et en cas d'absence l'ajoute |
| 306 | 65 * parametres: |
| 307 | 66 * root = pointeur pour la table de hachage |
| 308 | 67 * key = pointeur sur une chaine de caractères (la clé) |
| 309 | 68 * comportement: |
| 310 | 69 * La clé passée en parametre est comparé a celles présentes dans la |
| 311 | 70 * table de hachage. |
| 312 | 71 * retour: |
| 313 | 72 * Si la clé est trouvée alors la fonction retourne le champ data |
| 314 | 73 * sinon la fonction rend NULL. |
| 315 | 74 */ |
| 316 | 75 extern hte_data_t *hte_get (hte_root_t * root, char *key); |
| 317 | 76 |
| 318 | 77 |
| 319 | 78 /* ------------------------------------------------------------------------ */ |
| 320 | 79 |
| 321 | 80 |
| 322 | 81 /* |
| 323 | 82 * namealloc permet de garantir l'unicité des chaines de caractères |
| 324 | 83 * parametres: |
| 325 | 84 * name = chaine de caractères |
| 326 | 85 * comportement: |
| 327 | 86 * name est recherché dans la table, |
| 328 | 87 * s'il est absent on ajoute une copie de name dans la table |
| 329 | 88 * retour: |
| 330 | 89 * un pointeur sur la copie de la table |
| 331 | 90 */ |
| 332 | 91 char *namealloc (char *name); |
| 333 | 92 |
| 334 | 93 /* nombre maximum de noms dans la table */ |
| 335 | 94 #define MAX_NAMEALLOC 1000 |
| 336 | 95 |
| 337 | 96 |
| 338 | 97 /* ------------------------------------------------------------------------ */ |
| 339 | 98 |
| 340 | 99 /* |
| 341 | 100 * dejavu permet de savoir si un nom a déjà été vu |
| 342 | 101 * parametres: |
| 343 | 102 * name = chaine de caractères |
| 344 | 103 * comportement: |
| 345 | 104 * name est recherché dans la table, |
| 346 | 105 * s'il est absent on ajoute une copie de name dans la table |
| 347 | 106 * retour: |
| 348 | 107 * rend 1 s'il était déjà présent sinon 0 |
| 349 | 108 */ |
| 350 | 109 unsigned dejavu (char *name); |
| 351 | 110 |
| 352 | 111 /* nombre maximum de noms dans la table */ |
| 353 | 112 #define MAX_DEJAVU 1000 |
| 354 | 113 |
| 355 | 114 #endif |
| 356 | }}} |
| 357 | |
| 358 | '''hte.c''' |
| 359 | {{{ |
| 360 | 1 #include <stdio.h> |
| 361 | 2 #include <string.h> |
| 362 | 3 #include <stdlib.h> |
| 363 | 4 #include "hte.h" |
| 364 | 5 |
| 365 | 6 /* |
| 366 | 7 * Calcul de l'index de hachage de Donald Knuth |
| 367 | 8 * Elle produit un nombre entier à partir d'une chaine de caractères. |
| 368 | 9 */ |
| 369 | 10 unsigned hte_hash (char *key) |
| 370 | 11 { |
| 371 | 12 char *c = key; |
| 372 | 13 unsigned h; |
| 373 | 14 for (h = 0; *c; c++) |
| 374 | 15 { |
| 375 | 16 h += (h ^ (h >> 1)) + 314159 * (unsigned char) *c; |
| 376 | 17 while (h >= 516595003) |
| 377 | 18 h -= 516595003; |
| 378 | 19 } |
| 379 | 20 return h; |
| 380 | 21 } |
| 381 | 22 |
| 382 | 23 |
| 383 | 24 /* |
| 384 | 25 * Création d'un dictionnaire vide |
| 385 | 26 */ |
| 386 | 27 hte_root_t *hte_create (size_t nb_item) |
| 387 | 28 { |
| 388 | 29 hte_root_t *root; |
| 389 | 30 unsigned i, nb_list; |
| 390 | 31 static unsigned primes[] = { /*suite croissante de nombres premiers */ |
| 391 | 32 101, 149, 223, 347, 499, 727, 1163, 1697, 2503, 3989, 5839, 8543, |
| 392 | 33 12503, 20143, 29483, 43151, 63179, 92503, 101747, 148961, 218107, |
| 393 | 34 319313, 514243, 752891, 1212551, 1613873, 2599153, 3805463, |
| 394 | 35 5571523, 8157241, 11943011, -1 |
| 395 | 36 }; |
| 396 | 37 |
| 397 | 38 /* détermination de la taille réelle du dictionnaire */ |
| 398 | 39 for (i = 0; primes[i] < nb_item; i++); |
| 399 | 40 nb_list = primes[i]; |
| 400 | 41 if (nb_item != -1) |
| 401 | 42 { |
| 402 | 43 /* allocation et initialisation du dictionnaire */ |
| 403 | 44 if ((root = malloc (sizeof (hte_root_t)))) |
| 404 | 45 { |
| 405 | 46 root->NB_LIST = nb_list; |
| 406 | 47 if ((root->LIST = calloc (nb_list, sizeof (hte_item_t *)))) |
| 407 | 48 return root; |
| 408 | 49 } |
| 409 | 50 } |
| 410 | 51 fprintf (stderr, "hte_create: not enough memory\n"); |
| 411 | 52 exit (1); |
| 412 | 53 } |
| 413 | }}} |