|
|
@ -3,9 +3,86 @@ from data_structure import * |
|
|
|
class Expression: |
|
|
|
"""manipule les expression sous forme d'arbre""" |
|
|
|
def __init__(self, val, fils_gauche, fils_droit) -> None: |
|
|
|
self.Val = val |
|
|
|
self.val = val |
|
|
|
self.fils_gauche = fils_gauche |
|
|
|
self.fils_droit = fils_droit |
|
|
|
|
|
|
|
def evalue(self, val: float): |
|
|
|
pass |
|
|
|
def __str__(self) -> str: |
|
|
|
"""renvoie l'expression sous forme infixé""" |
|
|
|
if self.est_feuille(): |
|
|
|
return str(self.val) |
|
|
|
return '('+self.fils_gauche.__str__()+str(self.val)+self.fils_droit.__str__()+')' |
|
|
|
|
|
|
|
def est_feuille(self) -> bool: |
|
|
|
"""renvoie true si le noeud est une feuille""" |
|
|
|
if self.fils_droit is None and self.fils_gauche is None: |
|
|
|
return True |
|
|
|
return False |
|
|
|
|
|
|
|
def evalue(self) -> float: |
|
|
|
"""renvoie le résultat de l'expression""" |
|
|
|
if self.est_feuille(): |
|
|
|
return float(self.val) |
|
|
|
if self.val == '+': |
|
|
|
return self.fils_gauche.evalue() + self.fils_droit.evalue() |
|
|
|
if self.val == '*': |
|
|
|
return self.fils_gauche.evalue() * self.fils_droit.evalue() |
|
|
|
if self.val == '/': |
|
|
|
return self.fils_gauche.evalue() / self.fils_droit.evalue() |
|
|
|
if self.val == '^': |
|
|
|
return self.fils_gauche.evalue() ** self.fils_droit.evalue() |
|
|
|
if self.val == '-': |
|
|
|
return self.fils_gauche.evalue() - self.fils_droit.evalue() |
|
|
|
|
|
|
|
def npi2tree(expr: list) -> Expression: |
|
|
|
"""renvoie l'arbre formé a partir de l'expression donnée""" |
|
|
|
pile = Pile_chaine() |
|
|
|
for val in expr: |
|
|
|
if not val.isdigit(): |
|
|
|
# on inverse pour avoir les nombres dans le bon ordre |
|
|
|
nombre2, nombre1 = pile.depiler(), pile.depiler() |
|
|
|
pile.empiler(Expression(val, nombre1, nombre2)) |
|
|
|
else: |
|
|
|
pile.empiler(Expression(int(val), None, None)) |
|
|
|
return pile.sommet() |
|
|
|
|
|
|
|
def inf2npi(expr: list) -> list: |
|
|
|
operator_stack = Pile_chaine() |
|
|
|
operator_priority = { |
|
|
|
'+': 1, |
|
|
|
'-': 1, |
|
|
|
'*': 2, |
|
|
|
'/': 2, |
|
|
|
'(': 0, |
|
|
|
')': 0 |
|
|
|
} |
|
|
|
output = [] |
|
|
|
for val in expr: |
|
|
|
if val.isdigit(): |
|
|
|
output.append(val) |
|
|
|
else: |
|
|
|
if operator_stack.est_vide() or ( val == '(' or operator_priority[val] > operator_priority[operator_stack.sommet()]): |
|
|
|
operator_stack.empiler(val) |
|
|
|
else: |
|
|
|
while not operator_stack.est_vide(): |
|
|
|
if operator_stack.sommet() == '(': |
|
|
|
operator_stack.depiler() |
|
|
|
if operator_stack.est_vide(): # test si il y a un astérix avant la parenthèse |
|
|
|
output.append('*') |
|
|
|
elif operator_stack.sommet() != '*': |
|
|
|
output.append('*') |
|
|
|
else: |
|
|
|
output.append(operator_stack.depiler()) |
|
|
|
else: |
|
|
|
output.append(operator_stack.depiler()) |
|
|
|
if val != ')': |
|
|
|
operator_stack.empiler(val) |
|
|
|
while not operator_stack.est_vide(): |
|
|
|
output.append(operator_stack.depiler()) |
|
|
|
return output |
|
|
|
|
|
|
|
# [3, '-', 6, '*', 4, '+', 3] |
|
|
|
exp = inf2npi(list('6*(4+3)')) |
|
|
|
print(exp) |
|
|
|
|
|
|
|
print(npi2tree(exp)) |