====== Correction exercice 2 du TP1 ======
===== Question 1 =====
Implémenter la fonction ''est_element'' en Python.
D'abord un algorithme en pseudo-code :
FONCTION est_element
ENTRÉES:
Séquence
Item dont on veut savoir s'il est dans la séquence
SORTIE: si l'item appartient à la séquence, renvoie Vrai. Renvoie Faux sinon
DÉBUT
POUR CHAQUE item de la séquence FAIRE
SI item est celui cherché ALORS
on a trouvé !
RENVOYER Vrai
FIN
FIN
nous sommes arrivés au bout sans rien trouver...
RENVOYER Faux
FIN
Traduction en Python :
def est_element(L, a)
"""
L: Séquence
a: Item dont on veut savoir s'il est dans la séquence
Renvoie True si a appartient à L
"""
for item in L:
if item == a:
return True
return False
# j'ajoute les tests nécessaires
assert est_element([5,12,96,45,12], 4) == False # cas e absent
assert est_element([5,12,96,45,12], 96) == True # cas e présent 1 fois
assert est_element([5,12,96,45,12], 12) == True # cas e présent 2 fois
assert est_element([], 12) == False # cas L vide
Certains élèves sont embarrassés par le sujet qui leur dit qu'ils ne peuvent pas utiliser ''in'' pour résoudre directement le problème mais qu'ils doivent l'utiliser pour le ''for ... in''. C'est On rencontre parfois ce problème quand on essaie de simplifier un sujet. C'est parfois plus clair avec légèrement plus de complexité. Je vous propose donc une légère variation du sujet : supposez que la question soit : renvoyer Vrai **si L contient un diviseur de a**. Formulé ainsi, vous serez obligé de faire une boucle comme celle faite dans l'exercice. La fonction serait alors :
def contient_diviseur(L, a):
for item in L:
if item != 0 and a % item == 0:
return True
return False
===== Question 2 =====
Pour un algorithme s'appliquant à une donnée de taille n -- ici, n est la longueur de la liste : ''n = len(L)'', autrement dit le nombre d'éléments de L -- on veut évaluer le nombre d’opérations élémentaires pertinentes.
On pourra compter le nombre d'exécution de la comparaison « == ».
On étudie le comportement asymptotique de ce nombre.
* Dans le meilleur des cas, l'item recherché est le premier de la liste. On le trouve tout de suite. On n'a une seule comparaison à faire.
* Dans le pire des cas, l'élément n'est pas dans L. On est obligé de parcourir tous les éléments de L. On fait donc n comparaisons. Le coût est linéaire.
===== Question 3 =====
Écrire une fonction qui prend en argument une chaîne de caractères et un caractère 'c' et vérifie la présence ou pas du caractère dans la chaîne de caractères (et la tester).
C'est la magie de Python : il n'y a rien à changer !
>>>est_element("bonjour", "b")
True
>>>est_element("bonjour", "x")
False
===== Question 4 =====
Adapter, modifier, la fonction de la première question en demandant
* si ''a'' est présent, renvoyer l'indice de la première occurrence de ''a'' dans L
* sinon, renvoyer ''False''
Presque la même chose. Dans le cas où on trouve l'élément, au lieu de renvoyer ''True'', on renvoie l'indice.
FONCTION est_element
ENTRÉES:
Séquence
Item dont on veut savoir s'il est dans la séquence
SORTIE: si l'item appartient à la séquence, renvoie Vrai. Renvoie Faux sinon
DÉBUT
POUR CHAQUE item de la séquence FAIRE
SI item est celui cherché ALORS
on a trouvé !
RENVOYER l'indice
FIN
FIN
nous sommes arrivés au bout sans rien trouver...
RENVOYER Faux
FIN
Mais on est un peu ennuyé : dans le programme précédent, nous avons utilisé une boucle ''for item in L'' qui consiste à faire défiler les items présents dans ''L''. Mais on ne note pas les indices...
Il y a plusieurs façon de faire mais il y a toujours des méthodes simples en Python. Il y a notamment une astuce qui permet de parcourir simultanément les indices et les items d'une séquence :
def est_element(L, a)
"""
L: Séquence
a: Item dont on veut savoir s'il est dans la séquence
Renvoie l'indice de la première occurrence de a dans L, False sinon
"""
for indice, item in enumerate(L): # parcours simultané indice et item !
if item == a:
return indice
return False
===== Question 4 bis =====
Adapter, modifier, la première question en demandant
* si ''a'' est présent, renvoyer la liste des indices de toutes les occurrences de ''a'' dans L
* sinon, renvoyer ''False''
Grosse différence : Dans le programme précédent, sitôt que l'on trouvait une occurrence, on interrompait l'exécution de la fonction avec ''return''. Maintenant, on doit toujours aller au bout de la fonction pour compter toutes les occurrences.
FONCTION est_element
ENTRÉES:
Séquence
Item dont on veut savoir s'il est dans la séquence
SORTIE: la liste des indices de l'item,
False si l'item n'est pas présent
DÉBUT
initialiser une liste vide d'indices
POUR CHAQUE item de la séquence FAIRE
SI item est celui cherché ALORS
ajouter cette indice à la liste d'indices
FIN
FIN
SI la liste d'indices est vide ALORS
RENVOYER False
SINON
RENVOYER la liste d'indices
FIN
FIN
def est_element(L, a)
"""
L: Séquence
a: Item dont on veut savoir s'il est dans la séquence
Renvoie la liste des indices des occurrences de a dans L, False si aucune
"""
indices = []
for indice, item in enumerate(L): # parcours simultané indice et item !
if item == a:
indices.append(indice)
if indices == []:
return False
else:
return indices