Simplification d'une expresion

Gryzzly -  
 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

  1. dnt91 Messages postés 48 Statut Membre 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.
    0
    1. Gryzzly
       
      Salut,

      est ce que tu as une idée de la manière de simplifier l'arbre?
      0
  2. dnt91 Messages postés 48 Statut Membre 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à...
    0
    1. Gryzzly
       
      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. }
      0
      1. Gryzzly > Gryzzly
         
        Bonjour,

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