Informatique TP5 : Manipulations de chaînes et de listes CPP 1A
Transcription
Informatique TP5 : Manipulations de chaînes et de listes CPP 1A
Informatique TP5 : Manipulations de chaînes et de listes CPP 1A Thierno Barry, Julie Dumas, Frederic Devernay, Matthieu Moy Mars - avril 2016 Pour commencer, veuillez télécharger l’archive squelettes_tp5.zip qui contient les squelettes de tous les exercices de ce TP. Attention à ne pas travailler directement dans le fichier zip, vous devez extraire les fichiers avant. 1 Manipulation de chaînes de caractères La bibliothèque standard de Python contient beaucoup de fonctions de manipulations de chaînes évoluées. Le but ici est de retrouver les algorithmes sans utiliser ces fonctions. Le but de cette partie est d’écrire une fonction recherche_mot(m, t) qui recherche le mot m dans le texte t. m et t sont deux chaînes de caractères. L’algorithme est le suivant : pour chaque position i à l’intérieur de la chaîne t, on va vérifier si m correspond à la sous-chaîne de t démarrant à l’indice i. Exercice 1 Écrire une fonction coincide(t, i, m) qui renvoie True si la sous-chaîne de t démarrant à l’indice i et de la même longueur que m est égale à m, et False sinon. Par exemple, coincide("ceci est un test de texte", 12, "test") et coincide("ceci est un test de texte", 0, "ceci") renvoient True, mais coincide("ceci est un test de texte", 11, "test") renvoie False. Exercice 2 (Recherche de sous-chaîne) En utilisant la fonction coincide(t, i, m), écrire une fonction recherche_mot(m, t) qui renvoie l’indice de t où se trouve le mot m s’il existe, et la valeur None sinon. Vérifiez sur quelques exemples que la fonction fonctionne comme prévu. Exercice 3 (Complexité) Quelle est la complexité de cet algorithme ? En pratique, on sait faire beaucoup mieux que cet algorithme, et arriver à un coût linéaire après un pré-traitement de la chaîne à rechercher (algorithme de Knuth-Morris-Pratt par exemple). Les mêmes algorithmes peuvent être utilisés avec autre chose que des chaînes de caractères (exemple : recherche d’un gêne dans une séquence d’ADN). 1 2 Manipulation de listes Rappels : 1 Une liste en python est un conteneur permettant de regrouper plusieurs données de natures différentes. Ces données peuvent ensuite être accédées grâce à leurs numéros d’emplacement, appelé indice. # Cr é ation d ' une liste vide >>> maListe = [] # liste vide >>> maListe = [ -5 , " bonjour " , 1.2] # liste avec des valeurs initiales # Lire / modifier un >>> maListe [0] -5 >>> maListe [0] = 10 >>> print ( maListe ) [10 , " bonjour " , 1.2 , é l é ment # Lire la valeur à l ' indice 0 # remplacer la valeur à l ' indice 0 par 10 42] # Ajouter un é l é ments dans une liste >>> maListe . append (42) # Ajoute 42 en fin de liste >>> print ( maListe ) >>> maListe . insert (0 , " slt " ) # Ajoute " slt " à l ' indice 0 ( d é but de liste ) >>> print ( maListe ) [ " slt " , 10 , " bonjour " , 1.2 , 42] # Supprimer un é l é ment d ' une liste >>> del maListe [3] # Supprime l ' é l é ment à l ' indice 3 >>> print ( maListe ) [ " slt " , 10 , " bonjour " , 42] >>> maListe . remove ( " bonjour " ) # Supprime l ' é l é ment " Bonjour " >>> print ( maListe ) [ " slt " , 10 , 42] Exercice 4 (Première occurrence) Écrivez une fonction occurrence(liste, valeur) qui renvoie l’indice de la première occurence de l’élément valeur dans liste liste. La fonction devra renvoyer None s’il n’y a aucun élément valeur dans la liste. Exemple : si liste = [-4, 3, 7, 3], alors occurrence(liste, 3) renverra : 1 et occurrence(liste, 5) renverra : None Exercice 5 (Nombre d’occurrences) Écrivez une fonction nb_occurrences(liste, valeur) qui renvoie le nombre d’occurences de l’élément valeur contenu dans la liste liste. Exercice 6 (Intercalage) Soient les listes suivantes : L1 = ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"] L2 = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] Écrivez un programme qui crée une nouvelle liste L3. Celle-ci devra contenir tous les éléments de L1 et L2 en les alternant, de telle manière que chaque nom de mois soit suivi du nombre de jours correspondant : ["janvier", 31, "février", 29, ... , "décembre", 31] Exercice 7 (Fusion de listes triées) Soient L1 et L2 deux listes triées dans l’ordre croissant. Écrivez un fonction fusion(L1, L2) qui fusionne L1 et L2 dans une troisième liste L3, de telle 1. cf : TP No 4 2 sorte que L3 soit aussi triée dans l’ordre croissant. Par exemple si L1=[5, 7, 25] et L2=[3, 15, 20], fusion(L1,L2) retournera L3=[3, 5, 7, 15, 20, 25]. Quelle est la complexité de cette opération ? Exercice 8 (découpage) Soit la liste L = [35, 72, -5, 50, 24, 19]. Ecrivez un programme qui crée deux nouvelles listes Lpaire et Limpaire, de telle sorte que Lpaire contienne tous les éléments pairs L et Limpaire tous les éléments impairs de L. Faites varier les éléments de L et vérifiez que votre programme fonctionne correctement. 3 Listes de Listes En python une liste peut en contenir une ou plusieurs autres, on parle alors d’une liste de listes, ou encore d’une à deux dimensions. Le fonctionnement reste analogiquement identique. # Cr é ation d ' une liste de listes >>> maListe = [[3 , 1] , [5 , -1] , [2 , 9]] # Ajouter une liste dans une liste >>> maListe . append ([20 , 87]) >>> print ( maListe ) [[3 , 1] , [5 , -1] , [7 , 9] , [20 , 87]] # Acc è s >>> maListe [2] [7 ,9] >>> maListe [2][0] 7 >>> maListe [2][1] 9 >>> maListe [3][1] = -100 >>> print ( maListe ) [[3 , 1] , [5 , -1] , [7 , 9] , [20 , -100]] # Taille de la liste >>> len ( maListe ) 4 # Taille de liste à l ' indice 0 >>> len ( maListe [0]) 2 Exercice 9 Soit la liste suivante : liste = [[0, "zéro"], [1, "un"], [2, "deux"], [3, "trois"], [4, "quatre"], [5, "cinq"], [6, "six"], [7, "sept"], [8, "huit"], [9, "neuf"] ]. Écrivez un programme permettant d’afficher cette liste sous la forme : 0 s’écrit : zéro 1 s’écrit : un etc. Bonus : Tri À présent, notre objectif d’écrire une fonction permettant de trier une liste d’entiers dans l’ordre croissant avec la méthode du tri par sélection, que vous verrez prochainement en cours. Pour cela, nous allons procéder comme suit : On veut trier la liste L 3 1. On crée une liste vide : maListe 2. Tant que L n’est pas vide 3. On calcule min = plus petit élément de L 4. On supprime min de L 5. On ajoute min à maListe 6. On recommence à l’étape No 2 Pour vous guider dans l’implémentation, un squelette de programme vous est fourni dans le fichier trie.py Exercice 10 Compléter la fonction minimum(liste) qui calcule et renvoie le plus petit élément de liste passée en argument. Exercice 11 Compléter la fonction trie(liste) pour réliser l’opération de trie avec la méthode décrite ci-dessus. Quelle est la compléxité de cette opération ? 4 4 Solutions Exercice 1 : En n’utilisant que les opérations de base : def coincide (t , i , m ): for j in range ( len ( m )): if t [ i + j ] != m [ j ]: return False # On a trouv é une diff é rence , pas # la peine de continuer la boucle . # Si on arrive ici , c ' est que la boucle a termin é et qu ' on # a compar é tous les caract è res . Les chaines coincident . return True Une autre solution en utilisant les tranches de tableaux Python : def coincide (t , i , m ): return t [ i : i + len ( m )] == m Exercice 2 : def recherche_mot (m , t ): for i in range (1 + len ( t ) - len ( m )): if coincide (t , i , m ): return i return None Exercice 3 : La fonction coincide fait len(m) itérations dans le pire cas. Elle est appelée 1 + len(t) - len(m) fois. La complexité est donc len(m)∗(1 + len(t) - len(m)) (pire cas). Exercice 4 : def occurrence ( liste , valeur ): for i in range ( len ( liste )): if liste [ i ] == valeur : return i return None Exercice 5 def nb_occurrences ( liste , valeur ): nb = 0 for i in range ( len ( liste )): if liste [ i ] == valeur : nb = nb + 1 return nb Exercice 6 L3 = [] for i in range ( len ( L1 )): L3 . append ( L1 [ i ]) L3 . append ( L2 [ i ]) Exercice 7 def fusion ( L1 , L2 ): L3 = [] i1 = 0 i2 = 0 while ( i1 < len ( L1 )) and ( i2 < len ( L2 )): if L1 [ i1 ] <= L2 [ i2 ]: L3 . append ( L1 [ i1 ]) i1 = i1 + 1 else : 5 L3 . append ( L2 [ i2 ]) i2 = i2 + 1 if i1 < len ( L1 ): for i in range ( i1 , len ( L1 )): L3 . append ( L1 [ i ]) else : # i2 < len ( L2 ) for i in range ( i2 , len ( L2 )): L3 . append ( L2 [ i ]) return L3 Exercice 8 Lpaire = [] Limpaire = [] for i in range ( len ( L )): if L [ i ] % 2 == 0: Lpaire . append ( L [ i ]) else : Limpaire . append ( L [ i ]) Exercice 9 # methode 1 for i in range ( len ( liste )): print ( liste [ i ][0] , " s ' é crit : " , liste [ i ][1]) # methode 2 for elm in liste : print ( elm [0] , " s ' é crit : " , elm [1]) Exercice 10 def minimum ( liste ): min = liste [0] for i in range ( len ( liste )): if liste [ i ] < min : min = liste [ i ] return min Exercice 11 def trie ( L ): maListe = [] while len ( L ) > 0: min = minimum ( L ) L . remove ( min ) maListe . append ( min ) return maListe La complexité du calcul du minimum d’une liste non triée de taille N est linéaire par rapport à N : O(N). La fonction trie réalise N calculs de minimums, et à chaque fois, la liste est diminuée d’un élément : O(N ) + O(N − 1) + O(N − 2) + . . . + O(N − (N − 1)) = O( N (N2−1) ) ≈ O(N 2 ) 6