TD INFORMATIQUE N°2 PC* 15-16

publicité
TD INFORMATIQUE N°2 PC* 15-16
Piles - Récursivité
1. Notation polonaise inverse
On souhaite réaliser un programme qui évalue des expressions arithmétiques écrites en notation polonaise
inverse (NPI). Dans cette notation les opérateurs arithmétiques (+,*,-,/) sont placés après leurs opérandes en
notation « post-fixée ».
Ainsi l’expression 2+3 s’écrit 2 3 + et l’expression 2+3*4 devient 2 3 4 * +. L’intérêt de cette notation est que
les parenthèses deviennent inutiles : par exemple l’expression (2+3)*4 s’écrit simplement 2 3 + 4 * (remarquer la
différence avec l’expression précédente).
On représentera l’expression en NPI par des listes contenant des réels et des chaines de caractères
(représentant les opérateurs). Par exemple, 6 2.18e5 + 3 * est représentée par la liste : [6, 2.18e5, '+', 3, '*'].
L’évaluation d’une expression en NPI nécessite une pile. L’idée consiste à parcourir la liste de gauche à droite
et à empiler chaque nombre rencontré. Lorsque l’élément courant est un opérateur, on dépile les deux
opérandes, on effectue le calcul et on empile le résultat.
a. Après avoir importé le module ClassePile (fichier ClassePile.pyc fourni, dont les méthodes et fonctions ont
été décrites en cours), écrire une fonction EvalueExpr(L) qui prend en paramètre la liste L définissant l’expression
en NPI et qui évalue et renvoie la valeur de l’expression.
Tester votre fonction avec le script principal suivant :
L=[1,5,'+',2,'+',-3,'*']
resultat=EvalueExpr(L)
print("Le résultat de l'expression représentée par :",L,"est :",resultat)
# On doit trouver -24
b. Modifier votre fonction EvalueExpr(L) pour ajouter les opérateurs unaires suivants :
'neg' opérateur qui prend l’opposé de son opérande
'abs' opérateur qui prend la valeur absolue
'inv' opérateur qui prend l’inverse
'²' opérateur qui prend le carré
Tester votre fonction avec le script principal et l’expression représentée par la liste suivante :
L=[1,5,'²','+',2,'+','neg',3,'inv','*','abs']
# On doit trouver 9.333...
2. Occurrences d’un caractère dans une chaine
Il s’agit dans cet exercice de compter le nombre de fois qu’apparait un caractère donné dans une chaine de
caractères.
a. Ecrire une fonction compte_iter(ch,c), où c contient un caractère et ch une chaine, qui compte le nombre de
fois qu’apparait c dans ch, selon un algorithme itératif.
b. Ecrire une fonction compte_rec(ch,c), où c contient un caractère et ch une chaine, qui compte le nombre de
fois qu’apparait c dans ch, selon un algorithme récursif.
Tester vos fonctions avec le script principal suivant :
L=["Si les végétaux s’appuyaient uniquement","sur le transport d’eau pour bouger, ils ne","pourraient pas
produire des mouvements","sur une échelle de temps plus petite que","celle donnée par le temps
poroélastique.","Pourtant, la figure 1 montre que de nombreuses","plantes franchissent largement cette","limite
hydrodynamique et rivalisent avec","les plus rapides mouvements rencontrés chez","le vivant. Comment font ces
champions","du règne végétal pour atteindre de telles","vitesses ? Nous allons voir que leur stratégie","commune
est d’utiliser une instabilité","mécanique, c’est-à-dire la libération rapide","d’énergie élastique au-delà d’un
certain seuil."]
c,i='e',0
for ch in L:
print(i, compte_iter(ch,c),compte_rec(ch,c))
i+=1
1
# On doit trouver
#044
#144
#255
#388
#466
#566
#666
#755
#866
#933
# 10 6 6
# 11 5 5
# 12 4 4
# 13 4 4
# 14 6 6
3. Evaluation d’un nombre écrit en base 3
Un nombre entier positif écrit en base 3 est représenté par une chaine de caractères qui ne contient que les
caractères '0', '1' et '2'. Par exemple, '22' représente le nombre décimal 8.
a. Ecrire une fonction ternaire(s) qui teste si une chaine de caractères s n’est constituée que de '0', '1' ou '2'.
b. Ecrire une fonction eval_iter1(s) qui calcule le nombre représenté par une chaine de caractères s ne
contenant que des '0', '1' ou '2' en utilisant un algorithme itératif. On s’appuiera sur le fait que la valeur du
nombre cn ...c1c0 est égale à : cn 3n + ... + c1 31 + c0 .
c. Ecrire une nouvelle version eval_iter(s) de la fonction en utilisant un algorithme itératif d’évaluation du
(
)
nombre écrit en base 3 basé sur l’algorithme de Horner : cn ...c1c0 vaut c0 + 3* c1 + 3* ( ...3* ( cn−1 + 3* cn ) ... ) .
d. Ecrire une version récursive eval_rec(s) basée sur l’algorithme de Horner.
Tester vos fonctions avec le script principal suivant :
print("Valeur décimale de 2201112 en b3 par algo iter1 : ",eval_iter1('2201112'))
print("Valeur décimale de 2201112 en b3 par algo iter : ",eval_iter('2201112'))
print("Valeur décimale de 2201112 en b3 par algo rec : ",eval_rec('2201112'))
# On doit trouver:
# Valeur décimale de 2201112 en b3 par algo iter1 : 1985
# Valeur décimale de 2201112 en b3 par algo iter : 1985
# Valeur décimale de 2201112 en b3 par algo rec : 1985
4. Test d’une particularité de l’écriture en base 3 d’un nombre
a. Ecrire une fonction test01_iter(n), basée sur un algorithme itératif, qui détermine si l’écriture en base 3 de
l’entier n ne contient que des '0' et des '1' (la fonction renvoie un booléen : True si c’est le cas, False sinon).
b. Ecrire une version récursive de cette fonction test01_(n).
Tester vos fonctions avec le script principal suivant :
for i in range(14):
print(i,end=' ')
print(test01_iter(i),test01_rec(i))
# On doit trouver:
# 0 True True
# 1 True True
# 2 False False
# 3 True True
# 4 True True
# 5 False False
# 6 False False
# 7 False False
# 8 False False
# 9 True True
# 10 True True
# 11 False False
# 12 True True
# 13 True True
2
Téléchargement