diff --git a/S2/TPA/.gitignore b/S2/TPA/.gitignore new file mode 100644 index 0000000..4d68079 --- /dev/null +++ b/S2/TPA/.gitignore @@ -0,0 +1,2 @@ +lexique* +anagrammes.txt \ No newline at end of file diff --git a/S2/TPA/Makefile b/S2/TPA/Makefile new file mode 100644 index 0000000..721d81b --- /dev/null +++ b/S2/TPA/Makefile @@ -0,0 +1,7 @@ +lexique.py: + wget "http://www.fil.univ-lille1.fr/~L1S2API/CoursTP/lexique.zip" + unzip lexique.zip + rm -rf lexique.zip + +clean: + rm -rf lexique* anagrammes* diff --git a/S2/TPA/tp4.py b/S2/TPA/tp4.py new file mode 100644 index 0000000..e42df58 --- /dev/null +++ b/S2/TPA/tp4.py @@ -0,0 +1,238 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +""" +TP AP1 +Licence SESI 1ère année +Univ. Lille 1 + +tp4.py + +TP 4 - Algorithmes de recherche + +""" + +__author__ = 'PREUD\'HOMME Geoffrey & BEAUSSART Jean-loup' +__date_creation__ = 'Tue, 24 Feb 2015 10:30:21 +0100' + + +def question(numero): + """ + int → ∅ + Affiche la question en cours + """ + print('\n***', 'Question', numero, '***') + + +def squestion(lettre): + """ + int → ∅ + Affiche la sous-question en cours + """ + print('\n%s)' % lettre) + + +question(1) # Programmer recherches seq, seq triée, dicho + + +def seq(l, a, b, x): + """ + list, int, int, a → (bool, int) + Renvoie un tuple contenant un booléen indiquant si l'élément x est dans la liste l entre les + bornes [a, b[, ainsi que sa position le cas échéant, -1 sinon, par méthode séquentielle. + CU : l une liste, a et b des ints tels que 0 ≤ a < b ≤ len(l) + """ + assert(type(l) == list), "l doit être une liste" + assert(type(a) == type(b) == int), "a et b doivent être des ints" + assert(0 <= a < b <= len(l)), "Il faut que 0 ≤ a < b ≤ len(l)" + + i = a + + while i < b and l[i] != x: + i += 1 + if i < b: + return (True, i) + else: + return (False, -1) + + +def seqTrie(l, a, b, x): + """ + list, int, int, a → (bool, int) + Renvoie un tuple contenant un booléen indiquant si l'élément x est dans la liste l triée entre + les bornes [a, b[, ainsi que sa position le cas échéant, -1 sinon, par méthode séquentielle. + CU : l une liste triée, a et b des ints tels que 0 ≤ a < b ≤ len(l) + """ + assert(type(l) == list), "l doit être une liste triée" + assert(type(a) == type(b) == int), "a et b doivent être des ints" + assert(0 <= a < b <= len(l)), "Il faut que 0 ≤ a < b ≤ len(l)" + + i = a + + while i < b and l[i] < x: + i += 1 + if i < b and l[i] == x: + return (True, i) + else: + return (False, -1) + + +def dicho(l, a, b, x): + """ + list, int, int, a → (bool, int) + Renvoie un tuple contenant un booléen indiquant si l'élément x est dans la liste l triée entre + les bornes [a, b[, ainsi que sa position le cas échéant, -1 sinon, par dichotomie. + CU : l une liste, a et b des ints tels que 0 ≤ a < b ≤ len(l) + """ + assert(type(l) == list), "l doit être une liste triée" + assert(type(a) == type(b) == int), "a et b doivent être des ints" + assert(0 <= a < b <= len(l)), "Il faut que 0 ≤ a < b ≤ len(l)" + + d = a + f = b - 1 + while d < f: + m = (d + f) // 2 + if l[m] < x: + d = m + 1 + else: + f = m + est_dedans = x == l[d] + return (est_dedans, d if est_dedans else -1) + + +def tricho(l, a, b, x): # TODO + """ + list, int, int, a → (bool, int) + Renvoie un tuple contenant un booléen indiquant si l'élément x est dans la liste l triée entre + les bornes [a, b[, ainsi que sa position le cas échéant, -1 sinon, par trichotomie. + CU : l une liste, a et b des ints tels que 0 ≤ a < b ≤ len(l) + """ + assert(type(l) == list), "l doit être une liste triée" + assert(type(a) == type(b) == int), "a et b doivent être des ints" + assert(0 <= a < b <= len(l)), "Il faut que 0 ≤ a < b ≤ len(l)" + + d = a + f = b - 1 + while d < f: + m1 = (d + f) // 3 + m2 = m1 * 2 + if l[m1] >= x: + f = m1 + elif l[m2] >= x: + d = m1 + 1 + f = m2 + else: + d = m2 + 1 + est_dedans = x == l[d] + return (est_dedans, d if x == l[d] else -1) + +question(2) # Utiliser LEXIQUE + +from lexique import LEXIQUE + +squestion('a') # Vérifier que LEXIQUE est triée + + +def est_trie(l): + """ + list → bool + Indique si la liste l est triée dans l'ordre croissant + """ + for i in range(len(l) - 1): + if not l[i] < l[i + 1]: + return False + return True + +print("Le test indiquant si LEXIQUE est trié retourne %s." % est_trie(LEXIQUE)) + +print("Le lexique est cependant bien trié, mais par ordre alphabétique, comprenant les accents dans\ +cet ordre, ce qui n'est pas l'ordre \"naturel\" de Python, qui se base sur le codage des \ +caractères") + +print( + "Création de LEXIQUE_TRIE, qui est une copie de LEXIQUE trié par l'ordre de Python") +LEXIQUE_TRIE = list(LEXIQUE) # Crée une copie +LEXIQUE_TRIE.sort() + +print("Le test indiquant si LEXIQUE_TRIE est trié retourne %s." % + est_trie(LEXIQUE_TRIE)) + +squestion('b') +# Effectuer de nombreuses recherches dans LEXIQUE +# et comparer les temps d'éxécution selon les +# algorithmes utilisés + +# Définition des éléments choisis pour la recherche +from random import randint, SystemRandom +from string import ascii_lowercase, ascii_uppercase + + +def motAleatoire(taille): + """ + int → str + Renvoie une mot aléatoire constitué de lettres (sans accent) minuscules et majuscules, et de + chiffres + """ + return ''.join(SystemRandom().choice(ascii_lowercase + ascii_uppercase) + for _ in range(taille)) + + +def creerListeRecherche(l, dans, hors): + """ + list, int, int → list + Crée une liste de termes dont `dans` sont contenus dans `l`, et `hors` sont des mots générés + aléatoirement. + """ + elements = list() + taille = len(l) + for _ in range(dans): + elements.append(l[randint(0, taille)]) + for _ in range(hors): + while True: + mot = motAleatoire(randint(2, 10)) + if mot not in l: + break + elements.append(mot) + return elements + +# Méthode de test des fonctions +from time import time +from sys import stdout + + +def mesure(methode, l, elements): + """ + function, list, list → ∅ + Mesure le temps mis pour rechercher les éléments elements dans l en utilisant methode et affiche + les résultats. + """ + t = len(l) + print("Test de la méthode %s..." % methode, end='') + stdout.flush() + debut = time() + for e in elements: + methode(l, 0, t, e) + fin = time() + print("\rLa méthode %s a pris %f secondes pour trouver %d éléments, soit %f secondes par \ +élément." % (methode, fin - debut, len(elements), (fin - debut) / len(elements))) + + +if __name__ == '__main__': + import sys + if len(sys.argv) == 1: + MESURE_DEFAUT = 500 + print("\nTest avec %d éléments pris exclusivement de LEXIQUE" % + MESURE_DEFAUT) + exclu = creerListeRecherche(LEXIQUE, MESURE_DEFAUT, 0) + mesure(seq, LEXIQUE, exclu) + mesure(seqTrie, LEXIQUE_TRIE, exclu) + mesure(dicho, LEXIQUE_TRIE, exclu) + + PART_DEHORS = 0.2 + print("\nTest avec %d éléments dont %d sont dans LEXIQUE" % + (MESURE_DEFAUT, (1 - PART_DEHORS) * MESURE_DEFAUT)) + exclu = creerListeRecherche(LEXIQUE, int( + (1 - PART_DEHORS) * MESURE_DEFAUT), int(PART_DEHORS * MESURE_DEFAUT)) + mesure(seq, LEXIQUE, exclu) + mesure(seqTrie, LEXIQUE_TRIE, exclu) + mesure(dicho, LEXIQUE_TRIE, exclu)