begin process at 2012 02 10 02:59:02
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > ALGORITHME POUR ÉVALUER LES EXPRESSIONS ARITHMETIQUES

ALGORITHME POUR ÉVALUER LES EXPRESSIONS ARITHMETIQUES


 Information sur la source

Note :
8,5 / 10 - par 2 personnes
8,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Classé sous :evaluation, expression arithmetique, expressions arithmetiques, piles, postfixée Niveau :Débutant Date de création :15/09/2008 Date de mise à jour :15/09/2008 18:23:12 Vu / téléchargé :12 420 / 466

Auteur : shnaykhs

Ecrire un message privé
Site perso
Commentaire sur cette source (3)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Ce code permet d'évaluer une expression arithmétique donné
exemples :

6*8+7/3
(7+11)*2-5
0+9+6-5*(-4+22)
etc...

Le programme détecte aussi les erreurs Syntaxique ou lexicale présente dans l'expression saisi.

Source

  • /*****************************************************************
  • *
  • * Programed By ShNaYkHs
  • * shnaykhs@gmail.com
  • *
  • *****************************************************************/
  • #include <stdio.h> /* Pour les Entrers/Sorties */
  • #include <stdlib.h> /* Pour l'Allocation dynamique et autre */
  • #include <string.h> /* Pour les fonctions de manipulation de chaines */
  • #include <ctype.h> /* Pour la fonction isdigit() */
  • #include <math.h> /* Pour la fonction pow() */
  • #define MAX_LEN 20 /* Langeur maximale de l'expression */
  • /* Definition du type elem pour les elements du vecteur */
  • typedef struct Elem
  • {
  • float data;
  • int flag; /* 0=>operateur. 1=>operande. 2=>paranthese, 3=>E ou e */
  • }
  • elem;
  • /* Definition du type stack pour la Pile */
  • typedef struct Stack
  • {
  • elem element; /* l'element du vecteur */
  • struct Stack *prev;
  • }
  • stack;
  • /********************** The Prototyps **********************/
  • int CorrectExpression (char*); /* Verifie si l'expression est correcte */
  • /**==================**/
  • int IsOperator (elem); /* Verifie si c'est un operateur */
  • int IsOperand (elem); /* Verifie si c'est un operande */
  • int Priority (elem); /* retourne la priorité d'un operateur */
  • elem Operation (float, float, float); /* calcule une operation simple */
  • /**==================**/
  • elem* CharToVector (char*, elem*, int*); /* chaine => vecteur d'elements */
  • stack* MakePostfixedForm (elem*, int); /* La pile de la forme postfixé */
  • float EvaluatPostfixedExpretion (stack*); /* Evalué l'expression */
  • /**==================**/
  • elem Pop (stack**); /* Depiler */
  • void Push (stack**, elem); /* Empiler */
  • void InitStack (stack**); /* Initialiser la pile */
  • int EmptyStack (stack*); /* Verifie si la pile est vide ou pas */
  • elem HeadStack (stack*); /* retourne l'element de tete de pile */
  • /******************** The main function ********************/
  • int main ()
  • {
  • char expr[MAX_LEN]; /* l'expression sous forme de chaine */
  • elem* expr_vect; /* pour l'expression sous forme d'un vecteur */
  • int len_vect;
  • stack *P;
  • float the_result;
  • /* demander la saisi tantque l'expression est incorrecte */
  • do
  • {
  • puts ("Donnez une Expression Arithmetique correcte:");
  • gets (expr);
  • }
  • while( ! CorrectExpression(expr) );
  • expr_vect = (elem*) malloc( MAX_LEN * sizeof(elem) );
  • expr_vect = CharToVector(expr, expr_vect, &len_vect);
  • P = MakePostfixedForm ( expr_vect, len_vect );
  • the_result = EvaluatPostfixedExpretion (P);
  • printf ("\n\nLe resultat est %f\n", the_result);
  • free( expr_vect );
  • printf("\nPress any key to exit ...\n");
  • getchar(); /* Juste pour metre en pause ... */
  • return 0;
  • }
  • /********************** The Functions **********************/
  • /**============= Verifie si un caractére est un operateur ou pas **/
  • int IsOperator ( elem E )
  • {
  • if( E.flag == 0 )
  • return 1; /* c'est un operateur */
  • return 0; /* ce n'est pas un operateur */
  • }
  • /**============= Verifie si un caractére est un operande ou pas **/
  • int IsOperand ( elem E )
  • {
  • if( E.flag == 1 )
  • return 1; /* c'est un operande */
  • return 0; /* ce n'est pas un operande */
  • }
  • /**============= retourne la proprieter d'un operateur **/
  • int Priority ( elem E )
  • {
  • /* L'element passé à Priority() est un operateur */
  • if( E.data=='*' || E.data=='/' || E.data=='%' )
  • return 2;
  • else if( E.data=='-' || E.data=='+' )
  • return 1;
  • else
  • return -1; /* erreur ! */
  • }
  • /**============= effectue l'operation x op y **/
  • elem Operation (float x, float y, float op)
  • {
  • elem ret;
  • ret.flag = 1; /* Le resultat de l'operation est un operande */
  • switch ((int)op)
  • {
  • case '+' : ret.data = x + y; break;
  • case '-' : ret.data = x - y; break;
  • case '*' : ret.data = x * y; break;
  • case '/' : ret.data = x / y; break;
  • case '%' : ret.data = (int)x % (int)y; break;
  • }
  • return ret;
  • }
  • /**============= retourne la taille du vecteur **/
  • elem* CharToVector(char* char_exp, elem* vect_exp, int *len_vect)
  • {
  • int i=0, j=0, i_tmp=0, is_unar_minus=0, len = strlen(char_exp);
  • int taille_en_plus = 0, taille_en_plus_E = 0; /* les taille à enlever */
  • char *tmp; /*Pour contenir le nombre temporerement sous forum d'une chaine*/
  • elem* vect;
  • while( i < len )
  • {
  • /* Si c'est ce caractére est un chifre */
  • if( isdigit(char_exp[i]) )
  • {
  • tmp = (char*) malloc(len);
  • /* Comstruire le nombre sous forme d'une chaine tmp */
  • while( (isdigit(char_exp[i]) || char_exp[i] == '.') && i<len )
  • {
  • tmp[i_tmp] = char_exp[i];
  • i_tmp++;
  • taille_en_plus++; /* ex: le nbr "548" est sur 3 position */
  • i++; /* passé à la case suivante de la chaine */
  • }
  • /* un nombre sur 3 position dans la chaine va devenir sur 1 seul
  • position (dans le vecteur), donc il y a 3-1 = 2 position en plus */
  • taille_en_plus--;
  • tmp[i_tmp] = '\0'; /* on termine la chaine tmp par '\0' */
  • vect_exp[j].flag = 1; /* c'est un operande */
  • if(is_unar_minus)
  • {
  • vect_exp[j].data = (-1)*atof(tmp);
  • is_unar_minus = 0; /* reinitialisé à FAUX */
  • }
  • else
  • vect_exp[j].data = atof(tmp);
  • j++; /* passé à la case suivante du vecteur */
  • free(tmp);
  • i_tmp = 0;
  • }
  • /* Si ce n'est pas un chifre, alors: */
  • else
  • {
  • /* Si le caractére - n'est pas précédé par un chifre (le - unaire) */
  • if( char_exp[i] == '-' && ! isdigit(char_exp[i-1]) )
  • {
  • is_unar_minus = 1; /* VRAI, c'est un - unaire */
  • i++;
  • }
  • else
  • {
  • vect_exp[j].data = char_exp[i]; /* le code ascii */
  • if( char_exp[i] == ')' || char_exp[i] == '(' )
  • vect_exp[j].flag = 2; /* indique que c'est soit ) ou ( */
  • else if( char_exp[i] == 'E' || char_exp[i] == 'e' )
  • vect_exp[j].flag = 3; /* indique que c'est un E */
  • else
  • vect_exp[j].flag = 0; /* c'est un operateur */
  • j++;
  • i++;
  • }
  • }
  • }
  • /* à la sortie de while, (len-taille_en_plus) == taille actuel de vect_exp */
  • /* Maintenant on va s'occuper des caractéres 'E' ou 'e' : */
  • vect = (elem*) malloc( (len - taille_en_plus) * sizeof(elem) );
  • for( i=0, j=0; i < (len-taille_en_plus); i++ )
  • {
  • if( vect_exp[i].flag != 3 ) /* si c'est un E ou e */
  • {
  • vect[j] = vect_exp[i];
  • j++;
  • }
  • else
  • {
  • /* aEb == a * pow(10, b) */
  • vect[j-1].data = vect_exp[i-1].data * pow(10, vect_exp[i+1].data);
  • i++;
  • taille_en_plus_E = taille_en_plus_E + 2;
  • }
  • }
  • *len_vect = len - taille_en_plus - taille_en_plus_E;
  • return vect; /* le vecteur qu'on cherche */
  • }
  • /**============= Les Algos de postfixation et d'evaluation: **/
  • /* la forme postfixee sera dans la pile P */
  • stack* MakePostfixedForm( elem* vect, int len_vect )
  • {
  • int i;
  • elem E;
  • stack *R, *P;
  • stack* D; /* Juste pour tester le Debugage, pour voir la forme postfixé */
  • InitStack (&P);
  • InitStack (&R);
  • for( i=0; i<len_vect; i++ )
  • {
  • if( IsOperand(vect[i]) )
  • Push(&R, vect[i]);
  • else if( IsOperator(vect[i]) )
  • {
  • while( !EmptyStack(P) && IsOperator(HeadStack(P)) &&
  • ( Priority(vect[i]) <= Priority(HeadStack(P)) ) )
  • {
  • E = Pop(&P);
  • Push(&R, E);
  • }
  • Push(&P, vect[i]);
  • }
  • else if( vect[i].data == '(' )
  • Push(&P, vect[i]);
  • else
  • {
  • while( (!EmptyStack(P)) && HeadStack(P).data != '(' )
  • {
  • E = Pop(&P);
  • Push(&R, E);
  • }
  • E = Pop(&P);
  • }
  • }
  • while( ! EmptyStack (R) )
  • {
  • E = Pop (&R);
  • Push (&P, E);
  • }
  • #if 1 /* Debugage pour voir la forme poste fixée. désactivé avec: #if 0 */
  • printf("\nForme postfixee de l'expression:\n");
  • D = P;
  • for( ; D != NULL; D = D->prev )
  • {
  • if(D->element.flag == 1)
  • printf("%.2f ", D->element.data);
  • else printf("%c ", (int)D->element.data);
  • }
  • #endif /* Fin Debugage ... */
  • return P;
  • }
  • /** Evaluation de l'expression à partire de sa forme postfixée **/
  • float EvaluatPostfixedExpretion( stack* P )
  • {
  • elem x, y, e;
  • stack *R;
  • InitStack( &R );
  • while( ! EmptyStack(P) )
  • {
  • e = Pop(&P);
  • if( IsOperand(e) )
  • Push(&R, e);
  • else
  • {
  • x = Pop (&R);
  • y = Pop (&R);
  • Push(&P, Operation (y.data, x.data, e.data));
  • }
  • }
  • /* le resultat de l'expression est dans R */
  • return R->element.data;
  • }
  • /******************************************************************
  • ************* Les fonctions classique sur les Piles : *************
  • *******************************************************************/
  • void Push (stack** S, elem E)
  • {
  • stack* tmp = malloc (sizeof (stack));
  • tmp->element = E;
  • tmp->prev = *S;
  • *S = tmp;
  • }
  • elem Pop (stack **S)
  • {
  • stack* tmp;
  • elem ret;
  • if( ! EmptyStack (*S) ) /* si la pile n'est pas vide */
  • {
  • tmp = *S;
  • *S = (*S)->prev;
  • ret = tmp->element; /* on va retourner cette element */
  • free(tmp);
  • return ret;
  • }
  • }
  • void InitStack( stack **S )
  • {
  • *S = NULL;
  • }
  • int EmptyStack (stack *S)
  • {
  • if( S == NULL )
  • return 1; /* Oui pile vide */
  • return 0; /* Pile non vide */
  • }
  • elem HeadStack ( stack *S )
  • {
  • return (S->element);
  • }
  • /** Verifie si l'expression est correcte ou pas **/
  • int CorrectExpression( char* expr )
  • {
  • char symbol[21] = "0123456789.eE()*/%+-"; /* il y a 20 symboles autorisés */
  • int i, j, trouve = 0, brackets = 0, len = strlen(expr);
  • /**========== Verification Lexicale: ==========**/
  • for( i=0; i < len; i++ )
  • {
  • trouve = 0;
  • /* Verifier si le expre[i] apartiens à la liste des symboles autorisé */
  • for( j=0; j < 20; j++ )
  • {
  • if( expr[i] == symbol[j] )
  • {
  • trouve = 1;
  • break;
  • }
  • }
  • /* s'il ne se trouve pas dans la liste des symboles autorisé : */
  • if( ! trouve )
  • {
  • printf("Erreur Lexicale: caractere non autoriser.\n");
  • return 0; /* Expression Incorrecte */
  • }
  • }
  • /**========== Verification Syntaxique: ==========**/
  • /* Verifier si le nbr de ')' est egale au nbr de '(' */
  • for( i=0; i < len; i++ )
  • {
  • if( expr[i] == '(' )
  • brackets++;
  • else if( expr[i] == ')' )
  • brackets--;
  • }
  • if( brackets > 0 )
  • {
  • printf("Il manque %d caractere ')' dans l'expression.\n", brackets);
  • return 0;
  • }
  • else if( brackets < 0 )
  • {
  • printf("Il manque %d caractere '(' dans l'expression.\n", (-1) * brackets);
  • return 0;
  • }
  • /* Verification de l'ordre des caracteres: */
  • for( i=0; i < len; i++ )
  • {
  • /* pour les caracteres + - * / % */
  • if( expr[i] == '+' || expr[i] == '/' || expr[i] == '*' ||
  • expr[i] == '%' || expr[i] == '-' )
  • {
  • /* si l'operateur ce trouve tout en debut ou en fin de l'expression: */
  • if( i == len-1 )
  • {
  • printf("Erreur Syntaxique: presence de caractere(s) mal placer.\n");
  • return 0; /* Expression Incorrecte */
  • }
  • else if( i == 0 )
  • {
  • if( expr[i] != '-' )
  • {
  • printf("Erreur Syntaxique: presence de caractere(s) mal placer.\n");
  • return 0; /* Expression Incorrecte */
  • }
  • else if( !( isdigit(expr[i+1]) || expr[i+1] == '(' ) )
  • {
  • printf("Erreur Syntaxique: presence de caractere(s) mal placer.\n");
  • return 0; /* Expression Incorrecte */
  • }
  • }
  • /* Dans le cas d'un operateur differant de '-' :
  • il faut que l'operateur soi suivi d'un nombre ou bien d'une '(' ou
  • bien un '-' ,ET, il faut qu'il soi préceder par un nombre
  • ou bien par une ')' , Dans le cas contrere, C'est une erreur */
  • else if( expr[i] != '-' )
  • {
  • if( !( (isdigit(expr[i+1]) || expr[i+1] == '(' || expr[i+1] == '-')
  • && (isdigit(expr[i-1]) || expr[i-1] == ')') ) )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0; /* Expression Incorrecte */
  • }
  • }
  • /* Si l'operateur est un '-' : */
  • else if( !( (isdigit(expr[i+1]) || expr[i+1] == '(' )
  • && (isdigit(expr[i-1]) || expr[i-1]==')' || expr[i-1]=='('||
  • expr[i-1] == 'E' || expr[i-1] == 'e' || expr[i-1]=='+'||
  • expr[i-1]=='*' || expr[i-1]=='/'||expr[i-1]=='%') ))
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0; /* Expression Incorrecte */
  • }
  • }
  • /* pour le caractere '(' */
  • if( expr[i] == '(' )
  • {
  • /* s'il ce trouve au début de l'expression */
  • if( i == 0 )
  • {
  • /* il faut qu'il soit suivi par soi un nbr soi '(' soi '-' */
  • if( ! (isdigit(expr[i+1]) || expr[i+1]=='(' || expr[i+1]=='-') )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • }
  • /* s'il ce trouve a la fin de l'expression, alors c'est une erreur */
  • else if( i == len-1 )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • /* s'il ce trouve quelque part dans l'expression */
  • else
  • {
  • if( ! ( (isdigit(expr[i+1]) || expr[i+1]=='(' || expr[i+1]=='-') &&
  • (expr[i-1]=='*' || expr[i-1]=='-'|| expr[i-1]=='/' ||
  • expr[i-1]=='+' || expr[i-1]=='%'|| expr[i-1]=='(') ) )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • }
  • }
  • /* pour le caractere ')' */
  • if( expr[i] == ')' )
  • {
  • /* s'il ce trouve a la fin de l'expression */
  • if( i == len-1 )
  • {
  • /* il faut qu'il soit preceder par soi un nbr soi ')' */
  • if( ! ( isdigit(expr[i-1]) || expr[i-1]==')' ) )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • }
  • /* s'il ce trouve au début de l'expression, alors c'est une erreur */
  • else if( i == 0 )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • /* s'il ce trouve quelque part dans l'expression */
  • else
  • {
  • if( ! ( (isdigit(expr[i-1]) || expr[i-1]==')') &&
  • (expr[i+1]=='*' || expr[i+1]=='-'|| expr[i+1]=='/' ||
  • expr[i+1]=='+' || expr[i+1]=='%'|| expr[i+1]==')') ) )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • }
  • }
  • if(expr[0]=='e' || expr[0]=='E' || expr[len-1]=='e' || expr[len-1]=='E' )
  • {
  • printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • else if( (expr[i] == 'E' || expr[i] == 'e' ) &&
  • (expr[i+1]== '*' || expr[i+1]== '/' || expr[i+1]== '+' || expr[i+1]== '%') )
  • {
  • printf("Erreur Syntaxique:nnn presence caractere(s) mal placer.\n");
  • return 0;
  • }
  • }
  • return 1; /* Expression correcte */
  • }
/*****************************************************************
*
*    Programed By ShNaYkHs
*    shnaykhs@gmail.com
*
*****************************************************************/


#include <stdio.h>  /* Pour les Entrers/Sorties */
#include <stdlib.h> /* Pour l'Allocation dynamique et autre */
#include <string.h> /* Pour les fonctions de manipulation de chaines */
#include <ctype.h>  /* Pour la fonction isdigit() */
#include <math.h>   /* Pour la fonction pow() */

#define MAX_LEN 20  /* Langeur maximale de l'expression */

/* Definition du type elem pour les elements du vecteur */
typedef struct Elem
{
   float data;
   int flag;  /* 0=>operateur.  1=>operande.  2=>paranthese, 3=>E ou e */
}
elem;

/* Definition du type stack pour la Pile */
typedef struct Stack
{
   elem element;  /* l'element du vecteur */
   struct Stack *prev;
}
stack;


/********************** The Prototyps **********************/
int CorrectExpression (char*);  /* Verifie si l'expression est correcte */
/**==================**/
int IsOperator (elem);  /* Verifie si c'est un operateur */
int IsOperand (elem);  /* Verifie si c'est un operande */
int Priority (elem);  /* retourne la priorité d'un operateur */
elem Operation (float, float, float);  /* calcule une operation simple */
/**==================**/
elem* CharToVector (char*, elem*, int*);  /* chaine => vecteur d'elements */
stack* MakePostfixedForm (elem*, int);  /* La pile de la forme postfixé */
float EvaluatPostfixedExpretion (stack*);  /* Evalué l'expression */
/**==================**/
elem Pop (stack**);  /* Depiler */
void Push (stack**, elem);  /* Empiler */
void InitStack (stack**);  /* Initialiser la pile */
int EmptyStack (stack*);  /* Verifie si la pile est vide ou pas */
elem HeadStack (stack*);  /* retourne l'element de tete de pile */




/******************** The main function ********************/
int main ()
{
   char expr[MAX_LEN];  /* l'expression sous forme de chaine */
   elem* expr_vect;  /* pour l'expression sous forme d'un vecteur */
   int len_vect;
   stack *P;
   float the_result;

   /* demander la saisi tantque l'expression est incorrecte */
   do
   {
      puts ("Donnez une Expression Arithmetique correcte:");
      gets (expr);
   }
   while( ! CorrectExpression(expr) );

   expr_vect = (elem*) malloc( MAX_LEN * sizeof(elem) );
   expr_vect = CharToVector(expr, expr_vect, &len_vect);

   P = MakePostfixedForm ( expr_vect, len_vect );

   the_result = EvaluatPostfixedExpretion (P);

   printf ("\n\nLe resultat est %f\n", the_result);

   free( expr_vect );
   printf("\nPress any key to exit ...\n");
   getchar();  /* Juste pour metre en pause ... */
   return 0;
}


/********************** The Functions **********************/

/**============= Verifie si un caractére est un operateur ou pas **/
int IsOperator ( elem E )
{
   if( E.flag == 0 )
         return 1;  /* c'est un operateur */

   return 0;  /* ce n'est pas un operateur */
}


/**============= Verifie si un caractére est un operande ou pas **/
int IsOperand ( elem E )
{
   if( E.flag == 1 )
         return 1;  /* c'est un operande */

   return 0;  /* ce n'est pas un operande */
}


/**============= retourne la proprieter d'un operateur **/
int Priority ( elem E )
{
   /* L'element passé à Priority() est un operateur */

   if( E.data=='*' || E.data=='/' || E.data=='%' )
      return 2;

   else if( E.data=='-' || E.data=='+' )
      return 1;

   else
      return -1;  /* erreur ! */
}


/**============= effectue l'operation x op y **/
elem Operation (float x, float y, float op)
{
   elem ret;
   ret.flag = 1;  /* Le resultat de l'operation est un operande */

   switch ((int)op)
   {
      case '+' :  ret.data = x + y;  break;
      case '-' :  ret.data = x - y;  break;
      case '*' :  ret.data = x * y;  break;
      case '/' :  ret.data = x / y;  break;
      case '%' :  ret.data = (int)x % (int)y; break;
   }

   return ret;
}


/**============= retourne la taille du vecteur **/
elem* CharToVector(char* char_exp, elem* vect_exp, int *len_vect)
{
   int i=0, j=0, i_tmp=0, is_unar_minus=0, len = strlen(char_exp);
   int taille_en_plus = 0, taille_en_plus_E = 0; /* les taille à enlever */
   char *tmp; /*Pour contenir le nombre temporerement sous forum d'une chaine*/
   elem* vect;

   while( i < len )
   {
      /* Si c'est ce caractére est un chifre */
      if( isdigit(char_exp[i]) )
      {
         tmp = (char*) malloc(len);

         /* Comstruire le nombre sous forme d'une chaine tmp */
         while( (isdigit(char_exp[i]) || char_exp[i] == '.') && i<len )
         {
            tmp[i_tmp] = char_exp[i];
            i_tmp++;
            taille_en_plus++;  /* ex: le nbr "548" est sur 3 position */
            i++;  /* passé à la case suivante de la chaine */
         }

         /* un nombre sur 3 position dans la chaine va devenir sur 1 seul
            position (dans le vecteur), donc il y a 3-1 = 2 position en plus */
         taille_en_plus--;

         tmp[i_tmp] = '\0';  /* on termine la chaine tmp par '\0' */
         vect_exp[j].flag = 1;  /* c'est un operande */
         if(is_unar_minus)
         {
            vect_exp[j].data = (-1)*atof(tmp);
            is_unar_minus = 0;  /* reinitialisé à FAUX */
         }
         else
            vect_exp[j].data = atof(tmp);
         j++; /* passé à la case suivante du vecteur */

         free(tmp);
         i_tmp = 0;
      }

      /* Si ce n'est pas un chifre, alors: */
      else
      {
         /* Si le caractére - n'est pas précédé par un chifre (le - unaire) */
         if( char_exp[i] == '-'  &&  ! isdigit(char_exp[i-1]) )
         {
            is_unar_minus = 1;  /* VRAI, c'est un - unaire */
            i++;
         }
         else
         {
            vect_exp[j].data = char_exp[i]; /* le code ascii */

            if( char_exp[i] == ')' || char_exp[i] == '(' )
               vect_exp[j].flag = 2;  /* indique que c'est soit ) ou ( */
            else if( char_exp[i] == 'E' || char_exp[i] == 'e' )
               vect_exp[j].flag = 3;  /* indique que c'est un E */
            else
               vect_exp[j].flag = 0;  /* c'est un operateur */

            j++;
            i++;
         }
      }
   }

   /* à la sortie de while, (len-taille_en_plus) == taille actuel de vect_exp */
   /* Maintenant on va s'occuper des caractéres 'E' ou 'e' : */

   vect = (elem*) malloc( (len - taille_en_plus) * sizeof(elem) );

   for( i=0, j=0; i < (len-taille_en_plus); i++ )
   {

      if( vect_exp[i].flag != 3 ) /* si c'est un E ou e */
      {
         vect[j] = vect_exp[i];
         j++;
      }

      else
      {
         /* aEb == a * pow(10, b) */
         vect[j-1].data = vect_exp[i-1].data * pow(10, vect_exp[i+1].data);
         i++;
         taille_en_plus_E = taille_en_plus_E + 2;
      }
   }

   *len_vect = len - taille_en_plus - taille_en_plus_E;

   return vect;  /* le vecteur qu'on cherche */
}




/**============= Les Algos de postfixation et d'evaluation: **/

/* la forme postfixee sera dans la pile P */
stack* MakePostfixedForm( elem* vect, int len_vect )
{
   int i;
   elem E;
   stack *R, *P;
   stack* D;  /* Juste pour tester le Debugage, pour voir la forme postfixé */

   InitStack (&P);
   InitStack (&R);

   for( i=0; i<len_vect; i++ )
   {
      if( IsOperand(vect[i]) )
         Push(&R, vect[i]);

      else if( IsOperator(vect[i]) )
      {
         while( !EmptyStack(P) && IsOperator(HeadStack(P)) &&
                ( Priority(vect[i]) <= Priority(HeadStack(P)) ) )
         {
            E = Pop(&P);
            Push(&R, E);
         }

         Push(&P, vect[i]);
      }

      else if( vect[i].data == '(' )
         Push(&P, vect[i]);

      else
      {
         while( (!EmptyStack(P)) && HeadStack(P).data != '(' )
         {
            E = Pop(&P);
            Push(&R, E);
         }
         E = Pop(&P);
      }
   }

   while( ! EmptyStack (R) )
   {
      E = Pop (&R);
      Push (&P, E);
   }


#if 1 /* Debugage pour voir la forme poste fixée. désactivé avec: #if 0 */
   printf("\nForme postfixee de l'expression:\n");
   D = P;
   for( ; D != NULL; D = D->prev )
   {
      if(D->element.flag == 1)
         printf("%.2f  ", D->element.data);
      else  printf("%c  ", (int)D->element.data);
   }
#endif /* Fin Debugage ... */

   return P;
}


/** Evaluation de l'expression à partire de sa forme postfixée **/
float EvaluatPostfixedExpretion( stack* P )
{
   elem x, y, e;
   stack *R;

   InitStack( &R );

   while( ! EmptyStack(P) )
   {
      e = Pop(&P);

      if( IsOperand(e) )
         Push(&R, e);

      else
      {
         x = Pop (&R);
         y = Pop (&R);
         Push(&P, Operation (y.data, x.data, e.data));
      }
   }

   /* le resultat de l'expression est dans R */
   return R->element.data;
}



/******************************************************************
************* Les fonctions classique sur les Piles : *************
*******************************************************************/


void Push (stack** S, elem E)
{
   stack* tmp = malloc (sizeof (stack));

   tmp->element = E;

   tmp->prev = *S;
   *S = tmp;
}


elem Pop (stack **S)
{
   stack* tmp;
   elem ret;

   if( ! EmptyStack (*S) ) /* si la pile n'est pas vide */
   {
      tmp = *S;
      *S = (*S)->prev;
      ret = tmp->element; /* on va retourner cette element */
      free(tmp);

      return ret;
   }

}


void InitStack( stack **S )
{
   *S = NULL;
}


int EmptyStack (stack *S)
{
   if( S == NULL )
      return 1;  /* Oui pile vide */

   return 0;  /* Pile non vide */
}


elem HeadStack ( stack *S )
{
   return (S->element);
}





/** Verifie si l'expression est correcte ou pas **/
int CorrectExpression( char* expr )
{
   char symbol[21] = "0123456789.eE()*/%+-"; /* il y a 20 symboles autorisés */
   int i, j, trouve = 0, brackets = 0, len = strlen(expr);

   /**========== Verification Lexicale: ==========**/

   for( i=0; i < len; i++ )
   {
      trouve = 0;

      /* Verifier si le expre[i] apartiens à la liste des symboles autorisé */
      for( j=0; j < 20; j++ )
      {
         if( expr[i] == symbol[j] )
         {
            trouve = 1;
            break;
         }
      }

      /* s'il ne se trouve pas dans la liste des symboles autorisé : */
      if( ! trouve )
      {
         printf("Erreur Lexicale: caractere non autoriser.\n");
         return 0;   /* Expression Incorrecte */
      }
   }

   /**========== Verification Syntaxique: ==========**/

   /* Verifier si le nbr de ')' est egale au nbr de '(' */
   for( i=0; i < len; i++ )
   {
      if( expr[i] == '(' )
         brackets++;
      else if( expr[i] == ')' )
         brackets--;
   }

   if( brackets > 0 )
   {
      printf("Il manque %d caractere ')' dans l'expression.\n", brackets);
      return 0;
   }
   else if( brackets < 0 )
   {
      printf("Il manque %d caractere '(' dans l'expression.\n", (-1) * brackets);
      return 0;
   }

   /* Verification de l'ordre des caracteres: */
   for( i=0; i < len; i++ )
   {
      /* pour les caracteres + - * / % */
      if( expr[i] == '+' || expr[i] == '/' || expr[i] == '*' ||
             expr[i] == '%' || expr[i] == '-' )
      {
         /* si l'operateur ce trouve tout en debut ou en fin de l'expression: */
         if( i == len-1 )
         {
            printf("Erreur Syntaxique: presence de caractere(s) mal placer.\n");
            return 0;   /* Expression Incorrecte */
         }
         else if( i == 0 )
         {
            if( expr[i] != '-' )
            {
               printf("Erreur Syntaxique: presence de caractere(s) mal placer.\n");
               return 0;   /* Expression Incorrecte */
            }
            else if( !( isdigit(expr[i+1]) || expr[i+1] == '(' ) )
            {
               printf("Erreur Syntaxique: presence de caractere(s) mal placer.\n");
               return 0;   /* Expression Incorrecte */
            }

         }

         /* Dans le cas d'un operateur differant de '-' :
            il faut que l'operateur soi suivi d'un nombre ou bien d'une '(' ou
            bien un '-'  ,ET, il faut qu'il soi préceder par un nombre
            ou bien par une ')' , Dans le cas contrere, C'est une erreur */
         else if( expr[i] != '-' )
         {
            if( !( (isdigit(expr[i+1]) || expr[i+1] == '(' || expr[i+1] == '-')
                    &&  (isdigit(expr[i-1]) || expr[i-1] == ')') ) )
            {
               printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
               return 0;   /* Expression Incorrecte */
            }
         }

         /* Si l'operateur est un '-' : */
         else if( !( (isdigit(expr[i+1]) || expr[i+1] == '(' )
             && (isdigit(expr[i-1]) || expr[i-1]==')' || expr[i-1]=='('||
                 expr[i-1] == 'E' || expr[i-1] == 'e' || expr[i-1]=='+'||
                 expr[i-1]=='*' || expr[i-1]=='/'||expr[i-1]=='%') ))
         {
            printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
            return 0;   /* Expression Incorrecte */
         }

      }

      /* pour le caractere '(' */
      if( expr[i] == '(' )
      {
         /* s'il ce trouve au début de l'expression */
         if( i == 0 )
         {
            /* il faut qu'il soit suivi par soi un nbr soi '(' soi '-'  */
            if( ! (isdigit(expr[i+1]) || expr[i+1]=='(' || expr[i+1]=='-') )
            {
               printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
               return 0;
            }
         }
         /* s'il ce trouve a la fin de l'expression, alors c'est une erreur */
         else if( i == len-1 )
         {
            printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
            return 0;
         }
         /* s'il ce trouve quelque part dans l'expression */
         else
         {
            if( ! ( (isdigit(expr[i+1]) || expr[i+1]=='(' || expr[i+1]=='-') &&
                    (expr[i-1]=='*' || expr[i-1]=='-'|| expr[i-1]=='/' ||
                     expr[i-1]=='+' || expr[i-1]=='%'|| expr[i-1]=='(') ) )
            {
              printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
              return 0;
            }
         }
      }

      /* pour le caractere ')' */
      if( expr[i] == ')' )
      {
         /* s'il ce trouve a la fin de l'expression */
         if( i == len-1 )
         {
            /* il faut qu'il soit preceder par soi un nbr soi ')'  */
            if( ! ( isdigit(expr[i-1]) || expr[i-1]==')' ) )
            {
               printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
               return 0;
            }
         }
         /* s'il ce trouve au début de l'expression, alors c'est une erreur */
         else if( i == 0 )
         {
            printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
            return 0;
         }
         /* s'il ce trouve quelque part dans l'expression */
         else
         {
            if( ! ( (isdigit(expr[i-1]) || expr[i-1]==')') &&
                    (expr[i+1]=='*' || expr[i+1]=='-'|| expr[i+1]=='/' ||
                     expr[i+1]=='+' || expr[i+1]=='%'|| expr[i+1]==')') ) )
            {
              printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
              return 0;
            }
         }
      }

      if(expr[0]=='e' || expr[0]=='E' || expr[len-1]=='e' || expr[len-1]=='E' )
      {
         printf("Erreur Syntaxique: presence caractere(s) mal placer.\n");
         return 0;
      }

      else if( (expr[i] == 'E' || expr[i] == 'e' ) &&
               (expr[i+1]== '*' || expr[i+1]== '/' || expr[i+1]== '+' || expr[i+1]== '%') )
      {
         printf("Erreur Syntaxique:nnn presence caractere(s) mal placer.\n");
         return 0;
      }

   }

   return 1;   /* Expression correcte */
}

 Conclusion

Tout ceci permet de ce familiariser avec l'utilisation de listes chainées (Piles) pour l'évaluation et la transformation en forme postfixée.

P.S. Le programme à été compilé et testé sous Windows avec le compilateur GCC (Gnu C Compiler).

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture OPÉRATIONS SUR LES MATRICES (TABLEAU À DEUX DIMENSIONS)

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

 Sources en rapport avec celle ci

EVALUER UNE EXPRESSION MATHÉMATIQUE par begueradj
Source avec Zip BIBLIOTHÈQUE DE GESTION DES PILES DYNAMIQUES EN C par Sunglasses
Source avec une capture EVALUATION D'UNE EXPRESSION PARENTHÉSÉE par elkasimi2007
Source avec Zip BIBLIOTHÈQUE DE GESTION DES PILES STATIQUES EN C par Sunglasses
Source avec Zip EVALUATION D'UNE EXPRESSION MATHÉMATIQUE COMPLEXE par Niels Abel

Commentaires et avis

Commentaire de yann_lo_san le 17/09/2008 21:14:33 9/10

Salut,

J'en avais besoin, j'avais la flemme, je le prends... et je te mets 9.

Commentaire de barbichette le 22/09/2008 08:15:57 8/10

C'est simple est clair...
J'ai fait un peu la même chose en Pascal, avec des nombres à virgules, des fonctions, des constantes...
Si quelqu'un à le courage de le traduire en C++, qu'il ne se gêne pas...
http://www.delphifr.com/ajoutcode.aspx?step=1&ID=45846
Perso, j'ai pas assez de compétence pour le faire (et pas le temps).

Barbichette

Commentaire de barbichette le 22/09/2008 08:17:19

je me suis trompé de lien...
http://www.delphifr.com/codes/EVALUATION-EXPRESSIONS-MATHEMATIQUES_45846.aspx
Voilà, c'est mieux...

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Evaluation d'expression booléennes saisies sous forme de cheînes de caractères [ par dahlsimus ] Bonjour,j'ai besoin d'aide pour réaliser un programme en C qui évalue des expressions booléennes saisies sous forme de înes de caractères (ex: ((a.b)+ evaluation des performance [ par da45 ] Savez vous &nbsp;un api &nbsp;ou une biblioth&#232;que qui permet l&#8217;&#233;valuation des performance&nbsp;d&#8217;un d'un Evaluation d'une expression arithmetique en assembleur [ par BOX11 ] <TD id=HB_Focus_Element vAlign=top width="100%" background="" height=250 UNSELECTAB Evaluation d'un vecteur de dimension n [ par pausecpp ] Bonjour,je veux faire un petit ( ou grand j'en ai aucune idée) programme qui demande à l'utilisateur d'entrer une fonction et un vecteur et de lui imp j'ai besoin d'un cours sur les listes et les piles en language c [ par anoir19 ] salut les amisje m'appelle anoir etudiant 2eme annéé informatique lmdj'ai besoin d'un cours sur les listes et les piles en language cmerci programmatin des piles et listes en C [ par amenienis ] Bonjour;SVP s'il ya qque qui peut me programmer cet algo en langage Ccar je ne sais pas comment on programme les listes et les piles?!/////Tour de bou Intersection de deux FIFO !!! [ par codecpp ] Bonjour à tous, Je cherche un algo optimal :) ou un code c :)) pour faire l'intersection de deux piles FIFO. Je cherche à trouver l'ensemble des poi les histoire de piles et de file..... [ par handetaker ] J'amerais avoir un site ou je peux avoirs des exercices avec leur corrections sur des piles et des files,si possible les arbres pour un Debutant.merci trier d'une liste chainee en utilisant 2 piles [ par bella086 ] bsr voila j'ai un petit bon disant grand pblm sur c++ je dois charger une pile p1 a partir dune liste chainee et puis trier la pile p1 a laide d'une Evaluation d'une expression char* ou string [ par tsonamir ] Je suis appelé à faire un tableur dont chaque cellule contient une formule de type string ou char*,où les seuls opérateurs trouvés sont + - * / ( ) [


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,794 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales