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