#! /usr/bin/env python3 """ python3 diu-dico-hash """ __author__ = "Nicolas Pronost and Laure Gonnord" __copyright__ = "Univ Lyon1, 2019" from libdiulistechainee import * # une librairie maison de listes triées. import matplotlib.pyplot as plt import time import sys sys.setrecursionlimit(10000) ################## Constantes ###################### TAILLE_TABLE = 308 ################## Fonction de hachage ###################### def asciss(mot): h = 0 for c in mot: h += ord(c) - 96 return h def hash(mot): return asciss(mot) % TAILLE_TABLE ################## Construction de la table ###################### def init_ht(ht): """ Construit une liste de TAILLE_TABLE listes chainees (triées) une nouvelle liste chainee sera obtenue en appelant ListeChainee() """ ht = [ListeChainee() for i in range(TAILLE_TABLE)] return ht def update_ht(mot, ht): """ Ajoute le mot dans la liste chainee triee à la case d'index hash(mot). Utiliser ajouterDansListeTriee. """ ht[hash(mot)].ajouterEnTete(mot) def load_ht(nomFichier, ht): """ Ajoute les mots du fichier dans la table de hachage """ with open(nomFichier) as fichier: for ligne in fichier: update_ht(ligne[:-1], ht) ################## Fonctionnalités de la table ###################### def afficheCollisions(ht): """ Imprime la taille de chaque liste contenue dans les cases de ht Utiliser la méthode nbElements() """ for lc in ht: print(lc.nbElements()) def nombresCollisions(ht): """ Calcule et retourne la taille des listeschainées pour chaque case de la table selon une forme utile pour les graphiques, ie : - la premiere liste contient les indices des cases - la deuxième la taille de la liste contenue. Utiliser la méthode nbElements() """ res = ([], []) for k,v in enumerate(ht): res[0].append(k) res[1].append(v.nbElements()) return res def max_hash(nomFichier): """ Retourne le couple (mot_max,hmax) du plus "grand" mot (au sens de asciss) et sa valeur de hachage """ mot_max = "" hmax = 0 with open(nomFichier) as fichier: for ligne in fichier: mot = ligne[:-1] ha = hash(mot) if ha > hmax: hmax = ha mot_max = mot return (mot_max, hmax) ####### Quelques fonctions de stats/dessin de figures qui font varier la taille de ht def stats_load(fichier): global TAILLE_TABLE ht = [] # affichage temps exec en fct de la taille de la table plt.figure() toplot = [] tailles_table = [10, 50, 100, 200, 400] for TAILLE_TABLE in tailles_table: ht.clear() startTime = time.time() init_ht(ht) load_ht(fichier, ht) toplot.append(time.time() - startTime) plt.plot(tailles_table, toplot, "-k") plt.title("Temps d'exécution vs. taille table") plt.grid(True) plt.show() # Affichage graphe du nombre de collisions pour plusieurs tailles. def stats_collisions(fichier): global TAILLE_TABLE ht = [] plt.figure() tailles_table = [10, 50, 100, 200, 400] colors_plot = ["r", "b", "k", "g", "m"] for i in range(len(tailles_table)): TAILLE_TABLE = tailles_table[i] init_ht(ht) load_ht(fichier, ht) (axisX, axisY) = nombresCollisions(ht) plt.plot(axisX, axisY, colors_plot[i], label="taille " + str(TAILLE_TABLE)) plt.grid(True) plt.legend(loc="upper right") # plt.title('Nb de collisions vs. taille table') plt.show() ################## Programme principal ###################### ht = [] # Ma table de hachage est une liste de listes chainées fichier = "dico.english" # initialisation et chargement de la table ht = init_ht(ht) load_ht(fichier, ht) # Affichage console du nombre de collisions #afficheCollisions(ht) # A décommenter (il faut numpy et mathplotlib) # # Affichage graphe du nombre de collisions # (axisX, axisY) = nombresCollisions(ht) # plt.figure() # plt.plot(axisX, axisY, '-k') # plt.title('Nombre de collisions vs. indice table') # plt.grid(True) # plt.savefig("collisions.pdf") # # # Mot de valeur de hachage max (mot_max, hmax) = max_hash(fichier) print('valeur de hachage max: '+str(hmax)+' pour le mot: '+mot_max) TAILLE_TABLE = hmax+1 init_ht(ht) load_ht(fichier, ht) print('Le mot '+mot_max+' doit être dans la liste : ', end='') ht[hmax].afficher() # # # Maintenant comparons wrt les tailles de ht. # stats_load(fichier) # stats_collisions(fichier)