Besoin d'aide dans l'ecriture d'un algo...!!! (PostFix)

diluman Messages postés 6 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 12 avril 2008 - 4 avril 2008 à 11:28
diluman Messages postés 6 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 12 avril 2008 - 12 avril 2008 à 13:00
L'algorithme suivant permet d'évaluer une expression postfix en utilisant une structure de pile (stack):
- initialiser la pile à 'vide'
- scanner la chaïne de caractères en input, un caractère à la fois dans s
- tant qu'il y a encore des caractères faire
           - s <== caractère suivant de la chaine
           - si s est un opérande (un chiffre) alors mettre s dans la pile //push(pile,s)
           - sinon //s est un opérateur et donc faire l'opération avec les 2 derniers opérandes de la pile
                     - op2 <== dessus de la pile  //op2=pop(pile)
                     - op1 <== dessus de la pile  //op1=pop(pile)
                     - évaluer res = op1 s op2
                     - mettre res dans la pile  //push(pile,res)
            - fin de sinon
- fin de tant querésultat final contenu de la pile //resultat pop(pile)

Une expression postfix ressemble a "34+52-*" évaluée à 21 ou "32^4*1-93/21+/+" évaluée à 36 ou encore "623+-382/+*2^3+" évaluée à 52.
On suppose que tous les opérandes sont compris entre 0 et 9.
ON DOIT CREER UNE CLASSE STACK AVEC LES ATTRIBUTS ET METHODES QUI CONVIENNENT.

N'hesitez pas si vous êtes intersé.....

17 réponses

Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
4 avril 2008 à 11:51
Salut:

Ceci est un trés bon exemple (http://www.javafr.com/code.aspx?id=39295) qui utilise même une grammaire pour les différentes expressions arithmétiques.
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
7 avril 2008 à 13:41
Pas dur: pour la pile, une classe toute bete contient un membre référençant un tableau de nombres (come tu as supposés que tous les opérandes sont entre  1 et 9 (ce qui est vrai pour les caractères lus de la chaine d'entrée, mais faux pour les opérandes provenant de l'évaluation puisque ton projet est sensé retourner des valeurs entières supérieures), un tableau d'int suffira. Ton objet pile prendra soin de vérifier dans ses méthodes "int depiler()" et "void empiler(int)" que les limites du tableau ne sont pas dépassées pour gérer l'allocation nécessaire.


Le code ci-dessous est très rudimentaire mais réponds au problème et démontre quelques dispositifs de base et conventions de codage couramment utilisés en Java (interfaces, types génériques pour la pile, abstraction, héritage...). Bien sur on pourrait avoir moins de classe, mais c'est une démo (en français ici, à titre didactique, bien que les programmeurs Java utilisent tous la terminologie anglaise).

À toi de commenter.
//----- 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' &amp;&amp; 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));
    }
}
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
7 avril 2008 à 13:43
correction pour la dernière classe (erreur de copier-coller)
// ------ Test.java -----
package com.javafr.évaluateur;
public class Test {
    public static main(final String args[]) {
        final String expression = args[0];
        final Évaluable évaluable = new ÉvaluateurSimplePostFixé();
        System.out.println(expression + " = " + évaluable.évaluerExpression(expression));
    }
}
0
diluman Messages postés 6 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 12 avril 2008
7 avril 2008 à 13:55
J'ai trouvé la solution mais differement, en utilisant la pile proposée par JAVA:

class Postfix {
    //Methode permettant d'effectuer les differentes opérations en
    //des operateurs introduits dans l'expression postfix.
    //Le resultat est retourné sous forme de String
    private String operate(String op, int oper1, int oper2) {
        if (op.equals("+")) {
            return Integer.toString(oper1 + oper2);
        }
        if (op.equals("-")) {
            return Integer.toString(oper1 - oper2);
        }
        if (op.equals("*")) {
            return Integer.toString(oper1 * oper2);
        }
        if (op.equals("/")) {
            return Integer.toString(oper1 / oper2);
        }
        if (op.equals("^")) {
            int res = 1;
            if (oper2 == 1) {
                return Integer.toString(oper1);
            } else {
                for (int iCpt = 0; iCpt < oper2; iCpt++) {
                    res = res * oper1;
                }//Effectue le calcul de la puissance               
                return Integer.toString(res);
            }

 
        }
        throw new IllegalArgumentException("Operateur non reconnu " + op);
    }


    //Méthode permettant d'évaluer l'expression postfix
    public int evaluation(String expression) throws EmptyStackException {
        Stack maPile = new Stack();//Initialisation de la pile
        int iCpt = 0;
        String valNumX, valNumY;
        Character s;
        while (iCpt < expression.length()) {//iCpt permet de scanner chaque caractère de la chaîne
            s = expression.charAt(iCpt);
            if (Character.isDigit(s)) {//Si le caractère est un opérande (chiffre)
                valNumX = Integer.toString(Character.getNumericValue(s));
                maPile.push(valNumX);//On le met dans la pile
            } else {//Sinon si le caractère est un opérateur; on fait l'opération avec les 2 derniers opérandes de la pile
                int op2 = Integer.parseInt((String) maPile.pop());
                int op1 = Integer.parseInt((String) maPile.pop());
                //On recupere le dernier et l'avant dernier opérande introduit
                valNumY = Character.toString(s);
                String res = (operate(valNumY, op1, op2));
                maPile.push(res);//On met le resultat dans la pile               
            }
            iCpt++;//On passe au caractère suivant
        }
        int reponse = Integer.parseInt((String) maPile.pop());
        return reponse;//On recupere le resultat final
    }
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
8 avril 2008 à 08:49
Effectivement, mais la question portait sur l'écriture d'une classe "Pile", avec les fonction nécessaires... La classe Stack de Java est plus complète. Le code ci-dessus est just une démo...
D'autre part ton code stocke des chaines dans la pile, et pas des nombres (ça oblige à faire des "ParseInt" sans arrêt, et il n'est pas précisé dans la question quelle est la précision attendue des résultats.
La fonction operate() fait l'équivalent de ce que fait mon switch proposé (pas besoin de convertir des caractères en chaines pour l'opérateur).
Tout mon code tiendrait dans une seule classe contenant toutes les méthodes, je me suis juste amusé à utiliser quelques principes de programmation Java (si on regarde bien la façon dont il est fait, l'évaluateur est fait pour avoir des classes dérivées permettant l'évaluation de plusieurs syntaxes (pas seulement postfixée dnas la dernière classe), en réutilisant les classes de base contenant l'évaluation des opérandes, opérations et conversion de type, et pour supporter plusieurs types numériques. L'éidée étant de faire des classes réutilisables profitant des délégations, et non un code spécifique.


Maintenant c'est toi qui posais la question si tu poenses que tu as la meilleure solution, pourquoi la chercher ici? Fais ce que tu veux alors, mais ta classe n'a pas énormément d'intéret en elle-meme (sauf pour ton propre exercice)
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
8 avril 2008 à 12:16
Juste une remarque: j'ai mis tous les noms en Français, avec leurs accents. On ne le sait pas assez mais c'est tout à fait légal en Java, les identificateurs ne sont pas restreint à l'alphabet latin de base utilisé en anglais, mais peuvent être n'importe quel caractère reconnus comme des lettres. On a donc même le droit de les écrire en idéographes han, en syllabes hiragana ou katakana, en hébreu ou en arabe, de même que le cyrillique ou le grec. Il y a quelques restrictions sur certains caractères autorisés dans les identicicateurs Unicode, mais pas en Java pour des raisons historiques. On a aussi le droit d'utiliser (ailleurs que dans le premier caractère) des chiffres non arabo-européens. Ceci dit, les conventions de nommage Java supposent, pour pouvoir les respecter, que l'écriture supporte deux casses (impossible en arabe, hébreu, japonais, chinois. Cependant j'ai vu des sources japonais remplacer la différence de casse par une différence hiragana/katakana.

Il faut évidemment que le source utilise un codage du jeu de caractères reconnu par le JRE (UTF-8 est reconnu partout, de même que US-ASCII et ISO-8859-1, mais pas Windows-1252 qui demande l'installation d'un JAR complémentaire optionnel pour supporter d'autres codages), et le préciser au compilateur qui lit les fichiers sources (par défaut il utilise ISO-8859-1, ça marche donc pour les identificateurs en français à condition de ne pas utiliser les rares 'œ' ou 'Œ' ou l'encore plus rare 'Ÿ' qui sont absent de ce jeu de caractères codés, mais les autres caractères accentués français y sont y compris les rares 'æ' et 'Æ').

Avoir des sources codés en UTF-8 est bien pratique pour permettre de mettre des commentaires en français, et ne pas mettre des "\uNNNN" partout dans les chaines présentes dans le code source (si on ne les a pas stockées dans des resource bundles). Dans mon environement, les paramètres du compilateur Java utilisent UTF-8 par défaut à la place de ISO-8859-1 (oui j'ai des morceaux de code qui contiennent du japonaius et de l'arabe, même s'ils ne sont pas utilisés dans les identificateurs de packages, classes, méthodes, champs ou variables).

(Cette remarque est aussi valable pour les identificateurs en XML, JavaScript/ECMAScript, J#, C#, et les versions récentes de C ou C++, avec quelques différences toutefois sur le sous-ensemble des caractères Unicode acceptés, en fonction de la version d'Unicode sur laquelle s'appuie la spécification normalisée de ces langages.)

Ceux qui sont alergiques à l'emploi de l'anglais partout, ou ceux qui doivent produire des documentations en français (certaines administrations françaises par exemple, dont les chefs de projet ne connaissent rien à l'anglais) peuvent alors utiliser JavaDoc  pour faciliter la génération de ces documentations en utilisant la langue qu'on leur impose pour cette doc (certaines administrations le demande): on s'épargne des heures de maintenance séparée de la documentation demandée si on peut le faire directement dans les sources où c'est bien plus facile de documenter en même temps que la programmation du code lui-même.

En revanche les conventions de nommages (non-compris la langue) en Java ne sont pas une option (même si Java ne les impose pas lui-même) c'est un outil facilitant la maintenance et la compréhension des programmes, etévitant bien des problèmes d'intégration de code. Elles sont quasiment parfaites en Java et faciles à utiliser et retenir (mais celles de la CLR de .Net avec C# ou J# sont horribles et absolument pas homogènes, on se retrouve avec des difficultés de nommage pour les identificateurs, des conflits de nom, des programmes ambigus à lire (nécessité de relire le source pour trouver où chaque identificateur est défini), et à programmer de façon aussi moche qu'on le faisait en C.
0
diluman Messages postés 6 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 12 avril 2008
8 avril 2008 à 12:34
Merci pour ta solution verdy_p, jsui encore debutant en java donc bcp de lacune, jfai just l essentiel... Tant ke sa marche mai g enregistrer ton algo, et j v essaié d'ameliorer le mien...
Merci
Eric
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
8 avril 2008 à 23:49
Ce code est sorti brut d'édition, il y a peut-être des petites erreurs mineures à corriger. C'est surtout une idée. Mais avant de le poster j'aurai quand même dû le tester (malheureusement pas de copier-coller qui marche sur ce forum, car "coller" est désactivé ici, peut-être pour éviter que certains "pompent" facilement du code écrit par d'autre et violent le droit d'auteur et les licences).
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
9 avril 2008 à 00:05
Problème plus difficile à résoudre pour toi si tu veux: même problème, mais avec la notation préfixée (l'opérateur précède ses deux opérandes). Par exemple "+12" donne 3 ( c'est-à-dire 1+2 en notation usuelle infixée) et "-+**225371" donne 40 (c.-à-d. 2*2*5+3*7-1).
C'est un peu plus dur cette fois. Indication: la pile doit stocker alternativement des opérateurs et des opérandes (ou bien il faut deux piles en parallèle mais ce serait du gachis) : c'est le cas aussi pour la notation infixée usuelle où l'opérateur est au milieu des opérandes, mais cette fois il faut en plus gérer les priorités opératoires pour savoir quand évaluer une opération, ce qui n'est pas le cas pour la notation préfixée qui n'a pas besoin de priorité opératoire). Je te laisse le soin d'étudier la question et la façon de gérer des types différents dans la même pile...
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
9 avril 2008 à 00:17
Dernier problème intéressant: convertir une expression infixée (avec ses priorités opératoires et ses parenthèses) en expression postfixée (sans parenthèses), et supportant aussi des opérateurs à un seul opérande (négation, !, ~) ou trois opérandes (? :). C'est ce que font tous les compilateurs...

Ajoute des opérateurs de comparaisons, et fait de l'évaluation paresseuse pour (?:) sans évaluer l'opérande inutilisé et sans aucune méthode récursive (ta pile devra être capable de stocker comme opérandes des morceaux d'expression déjà analysées mais non encore évaluées)

Après essaye de gérer des expressions contenant un nombre indéterminé de variables nommées librement (tu les géreras dans une HashMap), et utilise un Scanner capable de reconnaitre des nombres positifs quelconques dans les opérandes (non limités à un caractère) : à toi les joies de l'analyse lexicale...
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
9 avril 2008 à 00:46
Note: pour la notation préfixée, on pourrait éventuellement penser qu'il suffit de refaire la même chose que pour la notation postfixée en analysant la chaine en commençant l'analyse par la fin. C'est vrai si l'expression est effectivement dans une chaine dont ont connait dès le début la longueur totale, pourtant l'expression pourrait venir d'un InputStream virtuellement infini et pas question de lire le stream en entier jusqu'à la fin (et le stocker au fur et à mesure) pour commencer à le traiter ensuite. Et imagine que tu as des opérandes plus longs qu'un simple chiffre: des nombre en notation scientifique ou hexadécimale (contenant des "e" ou des "x" et même des signes d'exposants), et des noms de variables contenant des chiffres: écrire un scanner capable de faire la différence sans ambiguité est bien plus délicat à concevoir car on ne sait même pas durant la lecture par la fin si on a un nombre ou un nom de variable tant qu'on n'est pas sûr qu'il n'est pas plus long (c'est-à-dire tant que'on n'est pas encore au début de la chaine ou on n'a pas lu un opérateur ou séparateur).

Bref, réfléchis comment évaluer la notation préfixée en la lisant depuis le début de la chaine. Cette notation n'est pas "étrange", elle existe dans certains langages "proches" de Lisp. Si la structure de pile ne te plait pas, pense aux arbres binaires (comme le fait Lisp pour gérer des listes de listes et d'atomes).
0
diluman Messages postés 6 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 12 avril 2008
9 avril 2008 à 15:33
Tu aV totalement raison, j'été dans l erreur, g du tout recommencer, je deV créer ma propre classe avec toute ces methodes & attribut, en utilisant un tableau pour la structure de pile, donc la je recommence, et si tu es interessé, j t envoi la suite de ce que j'ai fai


a++++
0
diluman Messages postés 6 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 12 avril 2008
9 avril 2008 à 15:36
Et les deu labo qui suivent, j doi transformer une expression infix avec parenthèse en postfix et l'evaluer, ensuite une expressioni prefix en postfix
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
9 avril 2008 à 19:49
pour infixe->préfixe, le principe est le même:
seulement ta pile doit contenir alternativement soit un nombre soit un opérateur suivi d'un nombre nul ou supérieur de parenthèses ouvertes.
L'autre solution c'est que chaque niveau de pile contienne un structure:
* le nombre
* l'opérateur éventuellement absent qui suit ce nombre (l'opérateuril ne peut être absent qu'au sommet de la pile)
* le nombre de parenthèses ouvertes après l'opérateur (il doit être nul tant qu'il n'y a pas d'opérateur.
c'est bien pour ça que j'avais prévu le coup en te donnant une classe Pile<T>générique pour que tu puisse la paramétrer avec le type que tu veux.

Mais est-ce que tu connais les <génériques> de Java? (proches des templates de C++) Ça existe depuis la version Java 5 (d'il y a 4 ans environ) et en Java 6 actuel. C'est bien pratique, mais ça reste compatible au niveau binaire avec les classes non génériques (le type que tu passes en paramètre d'un générique est une classe donc dérivé de java.lang.Object; si tu regardes les colllections standards de Java dans la doc 1.4, ils n'existaient pas, mais il fallait utiliser un typecast à chaque référencement d'Object extrait d'une Collection pour le convertir dans la sous-classe; en Java 5, pratiquement tous ces typecasts disparaissent des sources, c'est le compilateur qui vérifie avant et automatiquement que les typecasts sont valides, et qui les génèrent implicitement).

C'est ce que j'ai mis dans ma classe Pile<T> similaire en tout point à la classe java.util.Stack<T> dans les librairies standards du JRE (mais simplifié: j'ai juste les méthodes essentielles plus la méthode purge(), pas toutes celles qui ajoutent la sérialisabilité, le hachage, la conversion en String lisible affichant autre chose que la référence au tableau...)

Note que poru convertir une expression dans une autre forme, tu n'es pas obligé de générer l'expression finale au fur et à mesure, car on peut aussi tout laisser dans la pile (sans rien dépiler), mais empiler à la place un opérateur, il suffit alors simplement d'afficher le contenu de la pile dans l'ordre de la base (en [0]) au sommet (jusqu'à [sommet] non compris) pour obtenir l'expression postfixée finale.

Sinon tu peux toujours essayer de concaténer des chaines, mais c'est assez lourd, je trouve, à cause des allocations multiples d'objets chaines intermédiaire (et de leur tableau de caractère interne pour leur stockage).  MAis tu pourrais utiliser un StringBuilder pour insérer des caractères en fin de chaîne (dans la conversion infixe->postfixe) ou en début de chaîne (dans la conversion infixe->préfixe).

Si tu n'as pas le droit d'utiliser StringBuilder, ce n'est ni plus ni moins qu'un objet contenant un tableau de caractères interne modifiable, avec des méthodes pour insérer des caractères et gérer les réallocations nécessaires du tableau interne si la longueur obtenue dépasse la capacité actuelle du tableau, et une surcharge de la méthode toString() pour générer une instance de String non mutable à partir du contenu d'une partie de ton tableau de caractères: StringBuilder.toString() utilise pour cela un des constructeurs publics de la classe String: String(char[], int position, int longueur) afin de copier et préserver cet extrait que tu lui donne dans la valeur de chaine non mutable.
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
9 avril 2008 à 19:54
Mais tout ça sent les exos classiques d'une classe de cours Java et techniques de compilation et un travail sur les automates finis. Je m'attendais à ce qu'on t'ai demandé la suite.

Si tu veux être bien noté, tu peux donner une solution simple avec les classes java.util du JRE, et une implémentation avec tes propres classes. Réécris le tout à ta sauce, tes profs connaissent certainement ce site et n'aimeraient pas que tu leur rende une solution repompée... Ajoute aussi tes commentaires (c'est pour ça que je n'en ai pas mis) à la norme JavaDoc, et un diagramme de classes avec une petite description de ta solution et pourquoi tu as choisi ce modèle (et en quoi il est eextensible et réutilisable) et ce sera parfait.
0
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
9 avril 2008 à 20:08
Conseil: pour ton travail, utilises Eclipse plutôt que de passer ton temps à taper des lignes de commandes et différents éditeurs de texte. Sur le marché du travail tout le monde utilises Eclipse (certains NetBeans).

Ce qu'on te demande c'est comprendre le code Java que tu écris et aborder la modélisation (ensuite tu en auras toujours besoin quand on te demandera d'utiliser des frameworks classiques comme Hibernates et Struts en environnement J2EE, ou utiliser des interfce JDBC pour bases de données MySQL ou Oracle, et développer tes beans, d'écrire des modules de tests automatisés JUnit, et déployer sur des serveurs d'applications JSP, Tomcat, Weblogic, IBM, ou Oracle ou encore faire du développement en "client lourd" avec Swing, AWT voire SWT, ou "clients légers" de type GWT pour déploiement sur postes clients web avec HTML, CSS, Javascript et des requêtes client-serveur ou notifications serveur-client en RPC avec du XML).

Entraine toi aussi à utiliser un gestionnaire de versions (CVS ou autre), et approdondis la modélisation en UML. Tu as des tas d'outils gratuits sur le web pour t'entrainer et des projets open-source pour te faire la main sur des projets plus complexes.
0
diluman Messages postés 6 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 12 avril 2008
12 avril 2008 à 13:00
Voila, le final:
G developé deux classes... Labo4 & MyStack

Labo 4:

public class Labo4 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        String expression = "";
        while (!(expression.equals("fin"))) {
            expression = saisieDonnée();
            if (expression.equals("fin")) {
                break;//Si l'utilisateur introduit "FIN", il met fin à la boucle
            } else {
                int res = evaluation(expression);
                System.out.println("L'expression postfix ' "+ expression+" ' est évaluée à: " + res);
            }
        }
    }

    public static String saisieDonnée() {
        String expression;
        expression = (JOptionPane.showInputDialog("Entrez une expression postfix"));
        return expression;
    }

    public static int Operate(Character op, int oper1, int oper2) {
        int rep = 0;
        if (op.equals('+')) {
            rep = (oper1 + oper2);
        }
        if (op.equals('-')) {
            rep = (oper1 - oper2);
        }
        if (op.equals('*')) {
            rep = (oper1 * oper2);
        }
        if (op.equals('/')) {
            rep = (oper1 / oper2);
        }
        if (op.equals('^')) {
            int res = 1;
            if (oper2 == 1) {
                rep = oper1;
            } else {
                for (int iCpt = 0; iCpt < oper2; iCpt++) {
                    res = res * oper1;
                }//Effectue le calcul de la puissance               
                rep = res;
            }
        }
        return rep;
    }

    public static int evaluation(String expression) {
        MyStack maPile = new MyStack();
        Character s;
        int i_Cpt = 0;
        while (i_Cpt < expression.length()) {
            s = expression.charAt(i_Cpt);
            if (Character.isDigit(s)) {
                maPile.push(Character.toString(s));
            } else {
                int op2 = maPile.pop();
                int op1 = maPile.pop();
                int res = Operate(s, op1, op2);
                maPile.push(Integer.toString(res));
            }
            i_Cpt++;
        }
        int reponse = maPile.pop();
        return reponse;
    }
}

et MyStack:

public class MyStack {

    String[] tabPile;
    int size;

    public MyStack() {
        tabPile = new String[100];
        size = 0;
    }

    public boolean isEmpty() {
        boolean rep = false;
        if (tabPile[0] == null) {
            rep = true;
        } else {
            rep = false;
        }
        return rep;
    }

    public void push(String s) {
        tabPile[size] = (s);
        size++;
    }

    public int pop() {
        int top = Integer.parseInt(tabPile[size - 1]);
        size--;
        return top;
    }

    public String topstk() {
        String top = (tabPile[size - 1]);
        return top;
    }

    public int nbrEle() {
        return size;
    }
}

Just pour information, j'utilise NetBean IDE 6.0.1 et pour l'instant, sa ne m a pa encor pozé grand probleme, aa+
0
Rejoignez-nous