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)
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
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
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:
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;
}
}
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;
}