Le problème consiste à créer une sorte de calculatrice qui permet de calculer les expressions écrites dans la notation polonaise inverse (NPI).
Cette notation transforme une expression écrite avec des paranthèses comme celle-ci « 3 × (4 + 7) » en une expression écrite différemment. Donc en notation polonaise inverse l'expression
« 3 × (4 + 7) » s'écrit « 4 7 + 3 × ».
On doit stocker tous les nombres qu'on croise. Bien sûr on parcours l'expression depuis son début. Quand on passe par un opérateur, on doit sortir du stockage les 2 derniers nombres enregistrés, faire un calcul de ces 2 nombres et l'opérateur puis stocker le résultat du calcul. À la fin du code, il n'y aura qu'une valeur stockée.
Pour une facilité de compréhension, voici un exemple : « 4 7 5 - 3 * + » qui peut aussi être écrit comme ceci « (7 - 5) x 3 + 4 ».
Entrée | Stockage des données |
---|---|
4 | 4 |
7 | 4 7 |
5 | 4 7 5 |
- | 4 2 |
3 | 4 2 3 |
* | 4 6 |
+ | 10 |
Le type que j'ai utilisé pour résoudre ce problème est une pile car dans l'énoncé il est dit qu'il faut les 2 dernières valeurs enregistrées pour faire le calcul. Et que la pile est le type de donnée où ce sont les derniers éléments enregistrés qui sortent en premier.
Mon code est en 2 parties.
La première partie est un test pour vérifier que le code est bien écrit et qu'il n'y aura pas de problème si l'expression fournie par l'utilisateur contient une erreur. Pour cela j'ai vérifié qu'il y a un opérateur de moins que de nombre et qu'il y a au moins 2 nombres au début de la formule arithmétique, sinon le premier calcul ne pourra pas être calculé et cela causera une erreur.
La deuxième partie parcourt le code et fait les calculs quand c'est nécessaire. Dans cette partie quand on croise un opérateur, on dépile les 2 dernières valeurs stockées et normalement s'il n'y a pas de problème de test alors les valeurs stockées sont uniquement des nombres. Après chaque calcul, on doit transformer le int en str sinon la fonction eval utilisée dans cette fonction ne fonctionnera pas car elle ne marche qu'avec des str.
from pile import PileOptim
def NPI (chaine : str) -> int :
"""calcule les expression écrite en NPI (qui est une notation qui change la forme d'une expression écrite de ça « 3 × (4 + 7) » à ça « 4 7 + 3 × ») et vérifie que les expressions fournies sont correctes"""
valeurS = chaine.split(' ')
operateur = '+-/*'
pile = PileOptim()
nb_de_nombre = 0
nb_d_operateur = 0
nb_de_tour =0
#vérifie que l'expression est bien écrite
for caractere in valeurS :
nb_de_tour += 1
if caractere not in operateur and isinstance(int(caractere),(int)) : #vérifie que la caractère est un nombre
nb_de_nombre +=1
if nb_de_tour ==2 and nb_de_nombre != 2 : #vérifie qu'il y a au moins 2 nombres au début de l'expression
return "L'expression fournie n'est pas écrite correctement. Nous ne pouvons pas faire le calcul."
else :
nb_d_operateur += 1
if nb_d_operateur+1 != nb_de_nombre : #il y a toujours un operateur de moins que de nombre c'est de la que vient le test
return "L'expression fournie n'est pas écrite correctement. Nous ne pouvons pas faire le calcul."
#Parcours l'expression pour faire le calcul
for caractere in valeurS :
#vérifie si le caractere n'est pas un operateur et ajoute le caractere actuel dans la pile si c'est le cas
if caractere not in operateur:
pile.empiler(caractere)
#dans le cas contraire on fait des calculs
else :
#sort les 2 derniers operandes de la pile
operande2 = pile.depiler() #d'abord operande2 car la 2eme valeur est la premiere dépilée
operande1 = pile.depiler()
#fait le calcul des 2 operandes avec le bon operateur grâce à la fonction eval et empile dans la pile le résultat
resultat = eval(operande1+caractere+operande2)
pile.empiler(str(resultat)) #le résultat du calcul est un int mais la fonction eval ne fonctionne qu'avec des str
resultat_calcul = pile.depiler()
return resultat_calcul
exp = "3 10 2 - *"
print(NPI(exp))
print()
exp1 = '6 8 - 9 + 8 7'
print(NPI(exp1))
print()
exp2 = '6 8 - 9 + / 7 - +'
print(NPI(exp2))
print()
exp3 = '4 8 + 3 *'
print(NPI(exp3))
print()
exp4 = '6 6 6 6 + + +'
print(NPI(exp4))
print()
exp5 = '4 7 5 - 3 * +'
print(NPI(exp5))
print()
exp6 = '6 + 6 6 7 + +'
print(NPI(exp6))