183 lines
4.5 KiB
Python
183 lines
4.5 KiB
Python
#! /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)
|