Connexion élèves

Choisir le(s) module(s) à installer :

Le type abstrait Dictionnaire

Le type abstrait dictionnaire (appelé aussi tableau associatif) et une structure de données dont le nom est très évocateur. Comme dans un dictionnaire linguistique, une clef (le mot) est associé à une valeur (la définition).
Par contre, contrairement à un dictionnaire linguistique, la structure de données n'est pas du tout ordonnée, nous verrons plus tard que le mode de recherche dans les dictionnaires est néanmoins très optimisé. Voici quelques exemples de données adaptées à cette structure :

dictionnaire

Un dictionnaire peut aussi regrouper plusieurs informations de natures différentes :

Ici prénom, nom, classe, spécialité 1, spécialité 2, option fac et date de naissance sont les clefs.
Et Léo, Gruoleb, 111, NSI, Latin, 03/12/2004 sont les valeurs.

Utiliser les dictionnaires python

Comme vous le savez, le type dictionnaire existe déjà en python, vous l'avez sûrement déjà expérimenté l’année dernière . Cependant, avant de "soulever le capot" du langage de programmation et de tenter de mettre en place nous même ce type abstrait de données nous allons un peu utiliser les dictionnaire en python, afin de nous remémorer leur fonctionnement.
Voici donc 2 exercices simples qui vous permettrons de vous remettre en tête le fonctionnement des dictionnaires en python.
Si vous manquez de bases...Tout est .

Manipulations de base

  1. définir le dictionnaire personne contenant les informations suivantes relatives à une personne :

    • Nom : Dupuis
    • Prénom : Jacque
    • Age : 30
  2. corriger l'erreur dans le prénom et afficher le dictionnaire. La bonne valeur est "Jacques".
  3. afficher la liste des clés du dictionnaire.
  4. afficher la liste des valeurs du dictionnaire.
  5. afficher la liste des paires clé/valeur du dictionnaire.
  6. afficher la phrase : "Jacques Dupuis a 30 ans" en utilisant le dictionnaire.

Lien vers les RÉPONSES

Score au Scrabble

Le dictionnaire scrabble ci-dessous contient la valeur de chacune des lettres de l'alphabet au Scrabble :


scrabble = {"A":1,"B":3,"C":3,"D":2,"E":1,"F":4,"G":2,"H":4,"I":1,"J":8,"K":10,"L":1,"M":2,"N":1,"O":1,"P":3,"Q":8,"R":1,"S":1,"T":1,"U":1,"V":4,"W":10,"X":10,"Y":10,"Z":10}
			
  1. Écrire une fonction score qui calcule, en utilisant le dictionnaire scrabble, le score obtenu en plaçant un mot passé en argument à la fonction ( sans tenir compte des cases bonus : lettre compte-double, mot compte-triple, etc...)
  2. tester la fonction avec quelques mots ( en utilisant éventuellement le module doctest ) :
    
    score('NSI') = 3				
    score('BONJOUR') = 16
    score('KIWI') = 22
    score('ANTICONSTITUTIONNELLEMENT') = 28			
    					
def score(mot: str)->int: '''Fonction qui calcule le score d'un mot placé au Scrabble ENTREE : mot = chaîne de caractères représentant le mot à évaluer SORTIE : le score associé à ce mot ''' pass

Lien vers les RÉPONSES

Primitives

Revenons maintenant au TAD "dictionnaire". Avant de l'implémenter étudions en détail ce TAD :

Pour "faire fonctionner" un dictionnaire, il faut disposer des opérations suivantes :

Comment coder un dictionnaire

Les dictionnaires peuvent être implémentées de différentes façons, comme vous avez déjà une bonne expérience de ce genre d'exercice nous n'aborderons qu'un seul codage :
Le codage grâce à un tableau indexé (une liste python).

codage par un tableau

Cette solution de codage va consister à stocker dans un tableau des tableaux de deux éléments, le premier étant la clef et le seconde la valeur.

implémentation dans un tableau

Vous devez coder les fonctions primitives suivantes :

  • creer_dico_vide():qui créé un dictionnaire vide
  • ajouter(dico,clef,valeur):qui ajoute dans le dictionnaire dico la clef clef et lui associe la valeur valeurla fonction renvoie le dictionnaire modifié
  • modif(dico,clef,valeur): qui modifie dans le dictionnaire dico la valeur associée à la clefclef. la fonction renvoie le dictionnaire modifié
  • supprimer(dico,clef):supprime dans le dictionnaire dicola clef clefet la valeur associée.
  • rechercher(dico,clef):recherche dans le dictionnaire dicola clef clef et affiche la valeur associée. Si la clef n'est pas présente dans le dictionnaire, un message d'erreur est affiché

Lien vers les RÉPONSES

Rechercher dans un dictionnaire en "temps constant" (O(1)) !

Comme vous avez pu le voir en codant la fonction rechercher, il est nécessaire de parcourir le dictionnaire pour trouver une clef...Pourtant une des particularités des dictionnaires (notamment en python), c'est de réaliser des recherches en "temps constant".
Cela signifie que le temps de recherche dans un dictionnaire n'augmente pas avec sa taille :

Il est aussi rapide de rechercher une clef dans un dictionnaire 100 éléments que dans un dictionnaire de 1 000 000 000 éléments !

Le principe

Une seule question : comment ça marche ?
Et bien contrairement à ce que nous avons fait dans la partie précédente, les clef ne sont pas rangées au hasard en mémoire, mais leur place est déterminée par la valeur de la clef elle même. Il existe ainsi une fonction de hashage qui associe à chaque clef un entier qui déterminera la place des données stockées en mémoire. le processus se fait donc en deux temps :

Nous ne détaillerons pas les difficultés que l'on peut rencontrer pour construire une fonction de hashage, cependant :

Il est très difficile de construire une fonction de hashage fiable, car la diversité des clefs est potentiellement infinie et la fonction renvoie vers un nombre fini d'emplacements mémoire.
Il faut à tout prix éviter les collisions, c'est à dire que deux clefs différentes pointent vers le même emplacement mémoire.

Application simplifiée

Nous ne pouvons pas mettre en œuvre une fonction de hashage complexe (et d'ailleurs ce n'est pas au programme de terminale), mais pour bien comprendre le fonctionnement de la recherche en O(1) dans un dictionnaire vous allez améliorer votre travail précédent pour simuler la recherche en temps constant dans un dictionnaire.

Un contexte simplifié

Nous allons nous intéresser à un dictionnaire dont les clefs ne peuvent être que des caractères de la table AASCII. la taille du dictionnaire sera adonc limitée à 128 éléments maximum.
La fonction de hashage que nous allons utiliser est la fonction ord(). cette fonction renvoie le code ASCII correspondant à un caractère. Ainsi :


>>> ord('a')
97			
			

Vous devez donc modifier les fonctions primitives suivantes :

  • creer_dico_vide():qui créé un dictionnaire vide contenant 128 éléments ''
  • ajouter(dico,clef,valeur):qui ajoute dans le dictionnaire dico la clef clef et lui associe la valeur valeur la fonction renvoie le dictionnaire modifié. Le couple [clef,valeur]est insérer à l'index ord(clef)dans le tableau
  • rechercher(dico,clef):recherche dans le dictionnaire dico la clef clef et affiche la valeur associée. Si la clef n'est pas présente dans le dictionnaire, un message d'erreur est affiché. La recherche ne nécessite pas ici de boucle mais l'utilisation de la fonction ord() pour retrouver la place de la clef dans le tableau.

Lien vers les RÉPONSES

Comparaison des temps de recherche sur un tableau ou un dictionnaire en python

Nous allons maintenant faire quelques mesures de temps de recherche dans un tableau et dans un dictionnaire en utilisant les type construits existant dans python.
Voici la démarche que nous allons suivre :

La mesure de temps se fera grâce au module timeit qui permet de systématiser ce genre de tests. Voici le code de départ :

 
from random import *
from timeit import timeit

liste =[randint(0,1000) for i in range (1000000)]
dictionnaire={randint(0,1000): randint(0,1000) for i in range(1000000)}

print('liste : ',timeit(stmt='1001 in liste', globals=globals(), number=1000))
print('dictionnaire ',timeit(stmt='1001 in dictionnaire', globals=globals(), number=1000))
		

Les paramètres de timit sont les suivants :

Vous devez maintenant :

  1. Exécuter le code ci-dessus et noter les temps obtenus
  2. Diviser la taille des structures de données par 10 et noter les temps obtenus
  3. Multiplier la taille des structures de données par 10 et noter les temps obtenus (attention, cela va prendre un peu de temps...vous pouvez même prévoir la durée approximative de votre attente)
  4. Expliquer pourquoi vos mesurent confirment que le temps de recherche dans une liste est en O(n) alors que dans un dictionnaire il est en O(1).

Lien vers les RÉPONSES