Simplification d'une expresion

[Fermé]
Signaler
-
 Gryzzly -
Salut,
j'ai crée une fonction Eval qui évalue,une expression (arbre) lorsque toutes les feuilles de l'arbre sont des réels (de type double).
J'aimerais avoir une aide concernant la simplification de l'expression lorsque l'évaluation totale n'est pas possible.
Je m'explique:
si l'arbre est compose de + * 1 2 3 la fonction renvoie 5
mais si c'est + * 1 2 x la fonction renvoye 2+x

Code :

1. #include <stdio.h>
2. #include <string.h>
3. #include <stdlib.h>
4. #include <ctype.h>
5. #include <math.h>
6.
7.
8. enum Type {Operateur, Constante, Variable};
9.
10.
11. union Info
12. {
13. double cte;
14. char *nom;
15. char op;
16. };
17.
18. struct noeud{
19. enum Type type;
20. union Info info;
21. struct noeud *gauche;
22. struct noeud *droit;
23. };
24.
25. typedef struct noeud Noeud;
26. typedef struct noeud * Expression;
27.
28.
29.
30.
31.
32. double Eval(Expression *e)
33. {
34. double r1,r2;
35.
36. if((*e)->type == Constante) return((*e)->info.cte);
37.
38. if ((*e)->type == Operateur)
39. {
40. r1=Eval(&(*e)->gauche);
41. r2=Eval(&(*e)->droit);
42. switch ((*e)->info.op)
43. {
44. case '+':return(r1+r2);
45. case '-':return(r1-r2);
46. case '*':return(r1*r2);
47. case '/':return(r1/r2);
48. }
49. }
50. /* si aucun return n'a t effectu jusqu'ici*/
51. puts("erreur (code opratoire inconnu par exemple)");
52. return(0);
53. }
54.
55.
56. double Plus (double x, double y)
57. {
58. return x+y;
59. }
60.
61. double Moins(double x, double y)
62. {
63. return x-y;
64. }
65.
66. double Mul(double x, double y)
67. {
68. return x*y;
69. }
70.
71. double Div(double x, double y)
72. {
73. return x/y;
74. }
75.
76.
77. double (*FonctionOperateur(char operateur))(double, double)
78. {
79. char ops[]={'+','-','*','/','\0'};
80. double (*fcts[])(double,double)={Plus,Moins,Mul,Div,NULL};
81. unsigned i;
82. for(i=0;fcts[i]!=NULL&&ops[i]!=operateur;++i);
83. return fcts[i];
84. }

2 réponses

Messages postés
48
Date d'inscription
mercredi 28 avril 2004
Statut
Membre
Dernière intervention
30 novembre 2007
41
Salut,

je pense que tu devrais juste surcharger des fonctions.
Par exemple pour le +, tu devrais avoir une autre fonction qui prend en paramètre un doube e un char et retourne un tableau de char ainsi si ton enntrée est de ce type, le résultat ne sera pas le meme.
Salut,

est ce que tu as une idée de la manière de simplifier l'arbre?
Messages postés
48
Date d'inscription
mercredi 28 avril 2004
Statut
Membre
Dernière intervention
30 novembre 2007
41
Qu'entends tu par simplifier l'arbre? Sois plus précis..
Je pensais que tes méthodes citées plus haut le faisait déjà...
Bonjour,
je te remets le code suivant mais compléter,pour que tu puisses le tester.

J'appelle simplification ceci.
J'ai crée une fonction Eval qui évalue une expression composé uniquement de valeur de type double.
Dans l'exemple que j'ai testé(cf le main),le programme me renvoie ceci:
(1.000000+2.000000)*3.000000->9.000000

Ce que je voudrais,c'est que le programme me renvoye un double comme dans le cas précédent lorsue l'expression se compose uniquement de "double" mais une expression simplifiée dans le cas suivant:
(1*2)+x->2+x


   1. #include <stdio.h>
   2. #include <string.h>
   3. #include <stdlib.h>
   4. #include <ctype.h>
   5.
   6.
   7. enum Type {Operateur, Constante, Variable};
   8.
   9.
  10. union Info
  11. {
  12.   double cte;
  13.   char *nom;
  14.   char op;
  15. };
  16.
  17. struct noeud{
  18.   enum Type type;
  19.   union Info info;
  20.   struct noeud *gauche;
  21.   struct noeud *droit;
  22. };
  23.
  24. typedef struct noeud Noeud;
  25. typedef struct noeud * Expression;
  26.
  27.
  28. Expression AnalyseExpression(char **ligne)
  29. {
  30.  
  31.   Expression e;
  32.   char c;
  33.  
  34.   while(**ligne == ' ') (*ligne)++;
  35.  
  36.   /* on est en fin de chaine */
  37.   if(**ligne == '\0')
  38.     {
  39.       fprintf(stderr,"erreur : il doit manquer des operandes\n");
  40.       return NULL;
  41.     }
  42.  
  43.   e = (Expression)malloc(sizeof(Noeud));
  44.   if(e == NULL) return e;
  45.  
  46.   /* c'est un chiffre */
  47.   if(isdigit(**ligne))
  48.     {
  49.       e->type = Constante;
  50.       sscanf(*ligne,"%lf ",&(e->info.cte));
  51.       while(isdigit(**ligne) || **ligne == '.') (*ligne)++;
  52.     }
  53.  
  54.   else
  55.     {
  56.       /* c'est une lettre */
  57.       if(isalpha(**ligne))
  58.     {
  59.       e->type = Variable;
  60.       sscanf(*ligne,"%s ",e->info.nom);
  61.       while(isalpha(**ligne)) (*ligne)++;
  62.     }
  63.       else
  64.     {
  65.       /* le caractere est un operateur */
  66.       c=*((*ligne)++);
  67.       if(c == '+' || c == '-' || c == '*' || c == '/')
  68.         {
  69.           e->type = Operateur;
  70.           e->info.op = c;
  71.           e->gauche = AnalyseExpression(ligne);
  72.           e->droit = AnalyseExpression(ligne);
  73.         }
  74.       else if(c == '@' || c == '~')
  75.         {
  76.           e->type = Operateur;
  77.           e->info.op = c;
  78.           e->gauche = AnalyseExpression(ligne);
  79.           e->droit = NULL;
  80.         }
  81.       else printf("Erreur,'%c' n'est pas un operateur prevu\n",c);
  82.     }
  83.     }
  84.   return e;
  85. }
  86.
  87.
  88.
  89. /* Affichage de l'arbre en infixe */
  90. void Infixe(Expression e)
  91. {
  92.   switch(e->type)
  93.     {
  94.     case Constante:
  95.       printf("%f",e->info.cte);
  96.       break;
  97.      
  98.     case Variable:
  99.       printf("%s",e->info.nom);
 100.       break;
 101.      
 102.     case Operateur:
 103.       switch(e->info.op)
 104.     {
 105.       case'+':
 106.         case'-':/* affichage infixe sans () */
 107.         Infixe(e->gauche);
 108.       if(e->info.op == '+') printf("+");
 109.       else printf("-");
 110.       Infixe(e->droit);
 111.       break;
 112.       case'*':
 113.         case'/':/* affichage infixe avec () */
 114.         if(e->gauche->type != Operateur)
 115.           Infixe(e->gauche);
 116.         else
 117.           {
 118.         printf("(");
 119.         Infixe(e->gauche);
 120.         printf(")");
 121.           }
 122.       if(e->info.op == '*') printf("*");
 123.       else printf("/");
 124.      
 125.       if(e->droit->type != Operateur)
 126.         Infixe(e->droit);
 127.       else
 128.         {
 129.           printf("(");
 130.           Infixe(e->droit);
 131.           printf(")");
 132.         }
 133.       break;
 134.       case'@':/* affichage prefixe */
 135.         printf("@");
 136.       Infixe(e->gauche);
 137.       break;
 138.       case'~':
 139.         printf("~");
 140.       Infixe(e->gauche);
 141.       break;
 142.     }
 143.     }
 144. }
 145.
 146.
 147. double Eval(Expression *e)
 148. {
 149.   double r1,r2;
 150.  
 151.   if((*e)->type == Constante) return((*e)->info.cte);
 152.  
 153.   if ((*e)->type == Operateur)
 154.     {
 155.       r1=Eval(&(*e)->gauche);
 156.       r2=Eval(&(*e)->droit);
 157.       switch ((*e)->info.op)
 158.     {
 159.     case '+':return(r1+r2);
 160.     case '-':return(r1-r2);
 161.     case '*':return(r1*r2);
 162.     case '/':return(r1/r2);
 163.     }
 164.     }
 165.   /* si aucun return n'a t effectu jusqu'ici*/
 166.   puts("erreur (code opratoire inconnu par exemple)");
 167.   return(0);
 168. }
 169.
 170. double (*FonctionOperateur(char operateur))(double, double)
 171. {
 172.   char ops[]={'+','-','*','/','\0'};
 173.   double (*fcts[])(double,double)={Plus,Moins,Mul,Div,NULL};
 174.   unsigned i;
 175.   for(i=0;fcts[i]!=NULL&&ops[i]!=operateur;++i);
 176.   return fcts[i];
 177. }
 178.
 179.
 180. int main (void)
 181. {
 182.   double res;
 183.   char *ligne = "* + 1 2 3";
 184.   Expression e = NULL;
 185.   e=AnalyseExpression(&ligne);
 186.   Infixe(e);
 187.   printf("->");
 188.   res=Eval(&e);
 189.   printf("%lf",res);
 190.   printf("\n");
 191.   return 0;
 192.  
 193. }
> Gryzzly
Bonjour,

je me réponds pour dire que j'ai réussi à trouver comment faire
Voila