//----- Pile.java ----- package com.javafr.évaluateur; public class Pile<T> { private static final int TAILLE_PAR_DÉFAUT = 16, TAILLE_INCRÉMENT = 16; private T[] éléments; private int sommet; public Pile() { this(TAILLE_PAR_DÉFAUT); } public Pile(final int tailleInitiale) { this.éléments = (T[])new Object[tailleInitiale]; this.sommet = 0; } public void purger() { this.sommet = 0; } public boolean estVide() { return this.sommet <= 0; } public T dépiler() { if (this.estVide()) throw new ArrayOutOfBoundException("Pile vide"); return this.éléments[--this.sommet]; } public void empiler(final T élément) { if (sommet >= valeur.length) { final T[] tempÉléments = (T[])new Object[sommet + TAILLE_INCRÉMENT]; System.arraycopy(this.éléments, 0, tempÉléments, 0, this.éléments.length); this.éléments = tempÉléments; } this.éléments[this.sommet++] = élément; } } //----- ExpressionInvalide.java ----- package com.javafr.évaluateur; public class ExpressionInvalide extends IllegalArgumentException { public ExpressionInvalide(final String expression, final String raison) { super("expression postfixée '" + expression + "' invalide : " + raison); } } //----- Évaluable.java ----- package com.javafr.évaluateur; public interface Évaluable { Number évaluerExpression(final String expression) throws ExpressionInvalide; } //----- ÉvaluateurAbstrait.java ----- package com.javafr.évaluateur; public abstract class ÉvaluateurAbstrait implements Évaluable { final Pile<Number> pile; public ÉvaluateurAbstrait() { this.pile = new Pile<Number>(); } protected void somme() { final Number op2 = this.pile.dépiler(); this.pile.empiler(this.somme(this.pile.dépiler(), op2)); } protected void différence() { final Number op2 = this.pile.dépiler(); this.pile.empiler(this.différence(this.pile.dépiler(), op2)); } protected void produit() { final Number op2 = this.pile.dépiler(); this.pile.empiler(this.produit(this.pile.dépiler(), op2)); } protected void division() { final Number op2 = this.pile.dépiler(); this.pile.empiler(this.division(this.pile.dépiler(), op2)); } protected void puissance() { final Number op2 = this.pile.dépiler(); this.pile.empiler(this.puissance(this.pile.dépiler(), op2)); } public abstract Number évaluerExpression(final String expression) throws ExpressionInvalide; // Ces méthodes pourraient être généralisées pour calculer avec d'autres types numériques // implémentant Number... Version simplifiée ici, ne gère que des Double. protected Number somme(Number op1, Number op2) { return résultat(new Double(op1.getDoubleValue() + op2.getDoubleValue())); } protected Number différence(final Number op1, final Number op2) { return résultat(new Double(op1.getDoubleValue() - op2.getDoubleValue())); } protected Number produit(final Number op1, final Number op2) { return résultat(new Double(op1.getDoubleValue() * op2.getDoubleValue())); } protected Number division(final Number op1, final Number op2) { return résultat(new Double(op1.getDoubleValue() / op2.getDoubleValue())); } protected Number puissance(final Number op1, final Number op2) { return résultat(new Double(Math.pow(op1.getDoubleValue(), op2.getDoubleValue()))); } // Par défaut sur des Double, pas de réduction de précision sur le résultat // donc retourne le nombre calculé inchangé. protected Number résultat(final Number résultat) { return résultat; } } //----- ÉvaluateurEntierSimplePostFixé.java ----- package com.javafr.évaluateur; public class ÉvaluateurEntierSimplePostFixé extends ÉvaluateurAbstrait { public ÉvaluateurEntierSimplePostFixé() { super(); } private void opérande(final char c) { // On peut empiler tout type Number évaluable comme un Double; // ici un Integer suffit. this.pile.empiler(new Integer(c - '0')); } protected Number résultat(final Number résultat) { // Réduction de précision des résultats sur un petit entier. // Attention ! Aucun contrôle de débordement de capacité ici. return new Integer(résultat.getByteValue()); } public Number évaluerExpression(final String expression) throws ExpressionInvalide { final int longueur = expression.length(); this.pile.purger(); final int résultat; try { for (int position = 0; position < longueur; position++) { final char c = expression.charAt(position); switch (c) { case '+': this.somme(); break; case '-': this.différence(); break; case '*': this.multiplication(); break; case '/': this.division(); break; case '^': this.puissance(); break; default: if (c >= '0' && c <= '9') { this.opérande(c); break; } throw new ExpressionInvalide(expression, "caractère '" + c + "' incorrect"); } } résultat = this.pile.dépiler(); } catch (ArrayOutOfBoundException exc) { throw new ExpressionInvalide(expression, "nombre d’opérandes insuffisant"); } if (pile.estVide()) return résultat; throw new ExpressionInvalide(expression, "trop d’opérandes"); } } // ------ Test.java ----- package com.javafr.postfix; public class Test { public static main(final String args[]) { final String expression = args[0]; final Évaluable évaluable = new ÉvaluateurPostFixé(); System.out.println(expression + " = " + évaluable.évaluerExpression(expression)); } }
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question