Cours 11 du 6 avril :

Utilisation des piles:
expressions arithmétiques

 

 

Expression arithmétiques formées à partir d'opérateurs binaires

·        forme préfixe: + a b.

o       On peut donner une définition récursive de ce qu'est une expression préfixe:

§         une expression préfixe est soit un nombre (a) soit un opérateur suivi d'une première expression préfixe suivie d'une deuxième expression préfixe (+ a b)

·        ExpressionPréfixe = opérateur ExpressionPréfixe ExpressionPréfixe

·        Expressionprefixe = nombre

 

·        forme infixe : (a + b) (avec parenthèses)

·        ExpressionInfixe = (  Expressioninfixe  opérateur ExpressionInfixe )

·        ExpressioInfixe = nombre

 

 

·        forme postfixe: + a b

·        ExpressionInfixe = Expressioninfixe  opérateur ExpressionInfixe opérateur

·        ExpressioInfixe = nombre

 

Exemples:

Une expression peut être représentée par un arbre:

qui correspond à

·        l'expression préfixe: + * a b * + a b c

·        l'expression infixe parenthèsée ((a * b) + ((a+b)* c))

·        l'expression postfixe : a b * a b + c* +

 

On obtient ces expressions à partir de l'arbre par un parcours (récursif) à partir de la racine:

 

 

 

 

On peut noter qu'il n'y a pas d'ambiguïté pour les expressions préfixes et postfixes : à  + * a b * + a b c ou à a b * a b + c* + ne correspond qu'un seul arbre, ce n'est pas la même chose pour une expression infixe si l'on supprime les parenthèses, à a*b+a+b*c correspond (par exemple) aussi à l'arbre:

 

 

 

 

 

 

 

 

 

 

 

 

 


qui correspond à l'expression ((((a*b)+a)+b)*c)

 

Expressions sous forme postfixe:

On peut déterminer qu'une expression est bien une expression postfixe avec un compteur de la manière suivante:

il s'agit d'une expression postfixe si et seulement si le compteur est toujours positif et sa valeur finale est égale à 1.

Exemple:

  a b * a b + c * +

0 1 2 1 2 3 2 3 2 1

 

Evaluation d'espressions sous forme postfixe

On peut aussi évaluer simplement l'expression sous forme postfixe avec une pile:

 

Exemple supposons que a=12, b=2 et c=4, on obtiendra successivement sur la pile:

 

             2     4

    2    12 12 14 14 56

12 12 24 24 24 24 24 24 80

      *         +    *   +

 

 

Considérons une classe de Pile pour contenir des entiers:

 

// Pile de Integer

// attention aux conversions automatiques entre Integer et int

class PileInt {

    private PileListe p;

    public PileInt(){p=new PileListe();}

    public PileInt(int n){this();};

    public void empiler(int i){

        p.empiler(i);

    }

    public int depiler(){

        return (Integer)(p.depiler());

    }

}

 

On notera que pour utiliser la classe Pile définie précédemment qui permet de construire des piles de Object, il faut passer par la classe emballage ("wrapper") qui permet d'avoir des objets qui représentent des entiers (un int n'est pas un objet!).

Remarques:

 

   public static int evalPost(String st) {

        char[] a = st.toCharArray();

        int N = a.length;

        PileInt s = new PileInt(N);

        for (int i = 0; i < N; i++) {

            if (a[i]==' ')continue;

            if (a[i] == '+')

                s.empiler(s.depiler() + s.depiler());

            if (a[i] == '*')

                s.empiler(s.depiler() * s.depiler());

            if ((a[i] >= '0') && (a[i] <= '9')){

                s.empiler(0);

                while((a[i] >= '0') && (a[i] <= '9')&& (i<N))

                    s.empiler(10*s.depiler() + (a[i++]-'0'));

                i--;

            }

        }

        return s.depiler();

    }

 

Remarques:

 

Évaluation d'une expression préfixe

Pour évaluer récursivement une expression préfixe, le principe est assez simple. rappelons qu'une expression sous forme préfixe est de la forme opérateur expression expression ou nombre.

 

    // evaluation récursive d une expresssion simple

    // sous forme préfixe contenue dans in

    static String in; // la chaîne à évaluer

    static int i=0;

    static int evalPre(){

        while (in.charAt(i)==' ')i++;

        if(in.charAt(i)=='+'){

            i++;

            return evalPre()+evalPre();

        }

        if(in.charAt(i)=='*'){

            i++;

            return evalPre()*evalPre();

        }

        int x=0;

        while(i<in.length() && (in.charAt(i)>='0') && (in.charAt(i)<='9')){

            x=10*x+(in.charAt(i)-'0');

            i++;

        }

        return x;

    }

}

Conversions

On peut sur le même préfixe convertir une expression sous forme préfixe en une expression parenthèsée sous forme infixe: au lieu de calculer le résultat on écrit sur la pile le résultat la chaîne de caractères.

 

    // conversion de Postfixe vers Infixe avec une PileTable

    public static String Post2Inf(String arg){

        char[] a = arg.toCharArray();

        int N = a.length;

        String tmp="";

        Pile s = new PileTable(N);

        for (int i = 0; i < N; i++) {

            if (a[i]==' ')continue;

            if ((a[i] == '+')||(a[i] == '*')){

                tmp=(String)s.depiler();

                s.empiler("("+s.depiler() +a[i]+ tmp+")");

            }

            if ((a[i] >= '0') && (a[i] <= '9')) {

                tmp="";

                while((a[i] >= '0') && (a[i] <= '9')&& (i<N))

                    tmp += a[i++];

                s.empiler(tmp);

            }

           

        }

        return (String) s.depiler();

    }

 

 

pour la conversion depuis une expression sous forme infixe avec parenthèses à une expression sous forme postfixe on peut aussi utiliser une pile: on empile les opérateurs, on écrit directement les nombres et on dépile quand on rencontre une parenthèse fermante:

 

   // conversion de Infixe à Postfixe

    public static String Inf2Post(String args) {

        char[] a = args.toCharArray();

        int N = a.length;

        Pile s = new PileTable(N);

        String res="";

        for (int i = 0; i < N; i++) {

            if (a[i] == ')')

                res = res + s.depiler()+" ";

            if (a[i] == '(') continue;

            if(a[i]==' ')continue;

            if ((a[i] == '+') || (a[i] == '*'))

                s.empiler(a[i]);

            if((a[i] >= '0') && (a[i] <= '9')){

                while ((a[i] >= '0') && (a[i] <= '9'))

                    res =res+a[i++];

                i--;

                res=res+" ";

            }

        }

        return res;

    }