Evaluer une expression mathématique

Contenu du snippet

/* ce programme vérifie bien la saisie correcte de votre expression*/
/*idem, il prend en compte le signe de la puissane ^ , le signe de modulo %,*/
/* aisni que les opérations arithmétiques usuelles : addition +,soustraction -,multiplication* et division / */
/*une fonction spéciale est implémentée afin d'éviter la division sur zéro */
/*remarque importane : */
/*mon programme prend en compte, dans l'ordre de précédence, les signes suivants (dans l'ordre de priorité) :*/
/* ( ),[ ], { }, ^ (signe de la puissance), * , / , % , + et enfin l'opérateur - */
/*des fonctions spéciales sont implémentées afin de vérifier si tout opérateur possède ses opérandes*/
/*de même, j'ai implémenté des fonctions qui vérifient si toutes les opérandes possèdent leurs opérateurs mathématiques logiques*/
/*si jamais une parenthèse ouvrante ou fermante de type ( ), [ ], ou { } est omise, mon programme vous signalera l'erreur en question */
/*vous devez saisir votre expression naturellement et mon programme se chargera de sa convertion en une expression postfixée */
/*équivalente, juste après, le programme procède à son évaluation algébrique*/
/*de même, mon programme vous donnera la notation (la forme) postfixée de votre expression où N est une opérande quelconque*/
/*de votre expression suivis des opérateurs logiques que vous avez saisis*/
/*les opérandes N saisis seront affichés dans l'ordre dans une ligne à part lors de l'exécution du programme*/
/*le compilateur que j'ai utilisé est le Borland C++ version 4.5 SOUS DOS */
/* exemple : 7+2(8+5) ici mon programme vous signalera une erreur car on doit mettre un opérateur logique entre 2 et ( */
/* exemple2 : 5+2^2 = 5+(2^2) =9 */
/*Compilateur: Borland C++ 4.52*/
/*Console DOS */
/*pour toute question concernant ce code, contacter moi sur : b.beguer@yahoo.com*/
/*www.begueradj.com*/

Source / Exemple :

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<dos.h>
#include<math.h>

typedef struct noeud
{
 char val;
 noeud *suivant;
} noeud;

typedef struct noeud1
{
 long int val;
 noeud1 *suivant;
} noeud1;

#define pile noeud *

#define pile1 noeud1 *

/*dans cette partie, je vais déclarer quelques opérations nécessaires pour manipuler notre pile*/

/*fonction pour ajouter un élément*/
pile1 empiler1 (pile1 pil, long int v);

/*fonction pour supprimer le sommet de la pile*/
pile1 depiler1  (pile1 pil, long int &v);

/*fonction servant à retourner le sommet de la pile uniquement*/
void top1 (pile1 pil, long int &v);

/*fonction pour vider la pile */
pile1 mettreazero1 (pile1 pil);

/*fonction pour vérifier si la pile est vide */
int vide1 (pile1 pil);

/*fonction pour ajouter un élément à la pile */
pile empiler (pile pil, char v);

/*fonction pour supprimer le sommet de la pile*/
pile depiler  (pile pil, char &v);

/*fonction pour retourner le sommet de la pile uniquement*/
void top (pile pil, char &v);

/*fonction pour vider la pile*/
pile mettreazero (pile pil);

/*fonction pour vérifier si la pile est vide */
int vide (pile pil);

/* cette fonction servira à la saisie d'un caractère par caractère et l'empilement en meme temps


*  cette fonction force l'utilisateur à n'accepter que les caractères corrects*/

pile saisie(pile pil)
{
 textcolor(15);
 cprintf("Veuillez saisir votre expression (puis appuyez sur ENTREE) :  ");
 gotoxy(1,3);
 char ch;

 do
 {
  ch=getch();
  if (ch>=48 && ch<=57 || ch>=40 && ch<=43 || ch==37 || ch==45 || ch==47 || ch==91 || ch==93 || ch==94 || ch==123 || ch==125)
  {
   putch(ch);
   pil=empiler(pil,ch);
  }
  else if (ch !=8 && ch !=13)
  {
   sound(400);
   delay(250);
   nosound();
  }
  /*ici, on doit tenir compte de la saisie de l'espace blanc*/
  if (ch==8)
  { putch(ch);
   putch(' ');
   putch(ch);
   if (!vide(pil))
    pil=depiler(pil,ch);

  }
 }
 /* lorsque l'utilisateur tape sur ENTREE, je dois sortir de la boucle*/
 while (ch!=13);
 return(pil);
}

/* renverser la pile de caractères*/
pile renverser_pil(pile pil)
{
 char c;
 pile temp=NULL;
 while (!vide(pil))
 {
  pil=depiler(pil,c);
  temp=empiler(temp,c);
 }
 return(temp);
}

/* renverser  la pile de type long*/
pile1 renverser_pil1(pile1 pil)
{
 long int c;
 pile1 temp=NULL;
 while (!vide1(pil))
 {
  pil=depiler1(pil,c);
  temp=empiler1(temp,c);
 }
 return(temp);
}

/*fonction pour extraire les nombres saisis et les stoker comme étant des entiers long dans la pile long*/
pile remplirno(pile1 *no,pile pil)
{
 int i,j;
 long int x;
 char ch;

 pile temp=NULL;
 pile tmp_no=NULL;

 do{
  i=0;
  /* incrémenter i tant que le caractère saisi est un chiffre et l'empiler juste après*/
  while (!vide((pil=depiler(pil,ch))) && ch>=48 && ch<=57)
  {
   i++;
   tmp_no=empiler(tmp_no,ch);
  }

  if (i)
  {
   temp=empiler(temp,'N');
   if (!(ch>=48 && ch<=57))
    temp=empiler(temp,ch);
   else
   {
    i++;
    tmp_no=empiler(tmp_no,ch);
   }
   /* convertir le chiffre saisi en long int (note: '0'=48) */
   tmp_no=depiler(tmp_no,ch);
   x=ch-48;
   for (j=1;j<i;j++)
   {
    tmp_no=depiler(tmp_no,ch);
    x=x+(ch-48)*pow(10,j);
   }


*no=empiler1(*no,x);
  }
  else
  {
   if(ch>=48 && ch<=57)
   { *no=empiler1(*no,ch-48);
    temp=empiler(temp,'N');
   }
   else
    temp=empiler(temp,ch);
  }
 } while (!vide(pil));
 temp=renverser_pil(temp);


*no =renverser_pil1(*no);
 return(temp);
}

/* copier la pile de type long */
pile1 copier_pil1(pile1 *src)
{
 pile1 dest=NULL;
 pile1 temp=NULL;

 long int ch;

 while (!vide1(*src))
 {


*src=depiler1(*src,ch);
  temp=empiler1(temp,ch);
  dest=empiler1(dest,ch);
 }
 temp=renverser_pil1(temp);
 dest=renverser_pil1(dest);


*src=temp;
 return(dest);
}

/* copier la pile de caractères*/
pile copier_pil(pile *src)
{
 pile dest=NULL;
 pile temp=NULL;

 char ch;

 while (!vide(*src))
 {


*src=depiler(*src,ch);
  temp=empiler(temp,ch);
  dest=empiler(dest,ch);
 }
 temp=renverser_pil(temp);
 dest=renverser_pil(dest);


*src=temp;
 return(dest);
}

/* afficher le message d'erreur*/
void erreur(char code)
{
 sound(400);
 delay(400);
 nosound();

 gotoxy(35,12);
 textcolor(4+128);
 cprintf("Erreur syntaxique dans votre expression.");
 gotoxy(35,14);
 switch (code){
 case 0:
    cprintf(") manquant");
    break;
 case 1:
    cprintf("] manquant");
    break;
 case 2:
    cprintf("} manquant");
    break;

 case 3:
    gotoxy(28,14);
    cprintf("Operateur sans operande.");
    break;
 case 4:
    gotoxy(28,14);
    cprintf("Operande sans operateur.");
    break;
 }

}
/* vérifier si la saisie est correcte sinon afficher le message d'erreur avec la fonction erreur précédente


*  il y a un compteur tel que i-- si opérande,i++  si opérateur et i==1 si il n'y a pas d'erreurs de saisie

*  pour les parenthèses, il y a une pile telle que lorsque l'on renctonre celle qui ferment on doit dépiler et on doit

* doit retrouver les parenthèses ouvrantes sinon erreur, et pour les parenthèses de fin la pile doit etre vide sinon erreur*/

int verifiersicorrect(pile *pil)
{
 int compteur=0;
 char ch,br;
 pile parenthese=NULL;
 pile temp=NULL;
 temp=copier_pil(pil);
 while (!vide(temp))
 {
  br=0;
  temp=depiler(temp,ch);
  if (ch=='N')
   compteur++;
  else if (ch==42 || ch==43 || ch==45 || ch==47 || ch==37 || ch==94)
   compteur--;
  else if (ch==41)
  { if (parenthese)
   {
    parenthese=depiler(parenthese,br);
   }
   if (br!=40)
   {     erreur(0); return(0);}
  }
  else if (ch==93)
  { if (parenthese)
   {
    parenthese=depiler(parenthese,br);
   }
   if (br!=91)
   {     erreur(1); return(0) ;}
  }
  else if (ch==125)
  { if (parenthese)
   {
    parenthese=depiler(parenthese,br);
   }
   if (br!=123)
   {     erreur(2);  return(0);}
  }
  else
   parenthese=empiler(parenthese,ch);

 }
 if (!vide(parenthese))
 { erreur(0);
  gotoxy(35,14);
  parenthese=depiler(parenthese,ch);
  if (ch!=40)
   cprintf("%c manquant",ch+2);
  else
   cprintf("%c manquant",ch+1);
  return(0);
 }

 if (compteur>1)
 {
  erreur(3);
  return(0);
 }
 else if (compteur<1)
 { erreur(4); return(0);}
 else
  return(1);
}
/* retourner la précédence 1 si ch1 est premier sinon la précédence 0 */
int prioritaire(char ch1,char ch2)
{
 if (ch1==40 && ch2!=40)
  return(0);
 else if (ch1=='^')
  return(1);
 else if ((ch1=='*' || ch1=='/' || ch1=='%') && ch2!='^')
  return(1);
 else if ((ch1=='+' || ch1=='-') && (ch2=='-' || ch2=='+'))
  return(1);
 else if ((ch1=='*' || ch1=='/' || ch2=='%') && (ch2=='/' || ch2=='*' || ch2=='%'))
  return(1);
 else
  return(0);
}

/*fonction pour convertir l'expression saisie en expression postfixée*/

pile postfixe(pile pil)
{
  pile temp=NULL;
  pile oprnd=NULL;
  char ch,ch2;
  while (!vide(pil))
  {
   pil=depiler(pil,ch);
   ch2=0;
   if (ch=='N')
  temp=empiler(temp,ch);
   else if (ch==42 || ch==43 || ch==45 || ch==47 || ch==37 || ch==94)
   {
  if (!vide(oprnd))
  { top(oprnd,ch2);
   while (prioritaire(ch2,ch) && !vide(oprnd))
   {
    oprnd=depiler(oprnd,ch2);
    temp=empiler(temp,ch2);
    if (!vide(oprnd))
     top(oprnd,ch2);
   }
  }
  oprnd=empiler(oprnd,ch);
   }
   else if (ch==41 || ch==93 || ch ==125)
   {
  do{
   if (!vide(oprnd))
    oprnd=depiler(oprnd,ch2);
   if (ch2!=40)
    temp=empiler(temp,ch2);
  }
  while (ch2!=40);
   }
   else
  oprnd=empiler(oprnd,40);

  }

  while (!vide(oprnd))
  {
  oprnd=depiler(oprnd,ch);
  temp=empiler(temp,ch);
  }
  temp=renverser_pil(temp);
  return(temp);
}

/* fonctions mathématiques pour : + - * / % et ^ */
long int ajouter(long int x,long int y)
{
 return(x+y);
}

long int dif(long int x,long int y)
{
 return(x-y);
}

long int mul(long int x,long int y)
{
 return(x*y);
}

long int div(long int x,long int y)
{

 if (y!=0)
  return(x/y);
}

long int mod(long int x,long int y)
{
 return(x%y);
}

/* évaluation  de notr eexpression postfixée après convertion */
void evaluation(pile *pil,pile1 *no)
{
 pile1 nos=NULL;
 long int x,y,z;
 char ch;
 while(!vide(*pil))
 {


*pil=depiler(*pil,ch);
  if (ch=='N')
  {


*no=depiler1(*no,x);
   nos=empiler1(nos,x);
  }
  else
  {
   nos=depiler1(nos,y);
   nos=depiler1(nos,x);

   switch (ch){
   case '+':
    z=ajouter(x,y);
    break;
   case '-':
    z=dif(x,y);
    break;
   case '*':
    z=mul(x,y);
    break;

   case '/':
    if (y==0)
    {
      textcolor(4+128);
      gotoxy(12,35);
      cprintf("Division par zero !");
      sound(500);
      delay(400);
      nosound();
      return;
    }
    z=div(x,y);
    break;
   case '^':
    z=pow(x,y);
    break;

   case '%':
    z=mod(x,y);
    break;
   }
   nos=empiler1(nos,z);
  }
 }
 gotoxy(10,23);
 textcolor(2);
 nos=depiler1(nos,z);
 cprintf("Resultat = %li",z);

}
/**********************************************************************************************/
/**********************************************************************************************/
/*                                début de notre programme principal                                                        */
/**********************************************************************************************/
/**********************************************************************************************/
int main(void)
{
 textmode(3);
 _setcursortype(_NOCURSOR);

 clrscr();
 textcolor(15);
 gotoxy(5,2);
 cprintf("Evaluation des expressions arithmetiques.");
 gotoxy(10,4);
 cprintf("www.begueradj.com");

 textcolor(2);
 gotoxy(1,10);
 cprintf("Prise en compte de : (^ puissance) (% modulo) et (* / - +) avec precedence ^ puis * / % puis + -");
 gotoxy(1,25);
 textcolor(129);
 cprintf("Appuyez sur n'importe quelle touche pour continuer ...");
 getch();

 pile input=NULL;
 pile1 num=NULL;

 pile tmp_in=NULL;
 pile1 tmp_no=NULL;

 do{
  clrscr();

  input=saisie(input);
  if (input)
  { input=renverser_pil(input);

   input=remplirno(&num,input);
   if (verifiersicorrect(&input))
   {

    input=postfixe(input);

    /* copier la pile pour que l'on puisse l'afficher*/
    tmp_in=copier_pil(&input);
    tmp_no=copier_pil1(&num);

    gotoxy(2,18);
    cprintf("Postfixe:");
    char c;
    gotoxy(5,19);
    while (!vide(tmp_in))
    {
     tmp_in=depiler(tmp_in,c);
     cprintf("%c",c);

    }
    gotoxy(2,20);
    cprintf("Valeurs:");
    long int cc;
    gotoxy(5,21);
    while (!vide1(tmp_no))
    {
     tmp_no=depiler1(tmp_no,cc);
     cprintf("%li ",cc);

    }

    evaluation(&input,&num);
   }
  }

  gotoxy(1,25);
  textcolor(129);
  cprintf("Appuyez sur n'importe quelle touche pour continuer, Esc pour terminer.");

  input=mettreazero(input);
  num=mettreazero1(num);
 }while ((getch())!=27);

 return(0);
}
/**********************************************************************************************/
/**********************************************************************************************/
/*                                           fin du programme principal                                                             */
/**********************************************************************************************/
/**********************************************************************************************/

/**********************************************************************************************/
/*implémentation des différentes fonctions et procédures déclarées là haut*/
/**********************************************************************************************/
pile empiler (pile pil, char v)
{
 pile temp;

 temp=(pile)malloc(sizeof(noeud));
 if (temp !=NULL)
 { temp->val=v;

  temp->suivant=pil;
 }
 else
 {
  printf("nDebordement.");
  exit(1);
 }
 return(temp);

}

pile depiler (pile pil, char &v)
{
 pile temp;

 if (pil==NULL)
 {
  printf("nPile vide.");
  exit(1);
 }
 else
 {
  v=pil->val;

  temp=pil;

  pil=pil->suivant;

  free(temp);

 }
 return(pil);
}

void top (pile pil, char &v)
{
 if (pil==NULL)
 {
  printf("nPile vide.");
  exit(1);
 }
 else
  v=pil->val;

}

pile mettreazero (pile pil)
{

 pile temp;

 while (pil != NULL)
 {
  temp=pil;

  pil=pil->suivant;

  free(temp);
 }
 return(NULL);

}

int vide (pile pil)
{
 if (pil==NULL)
  return(1);
 else
  return(0);
}

pile1 empiler1 (pile1 pil, long int v)
{
 pile1 temp;

 temp=(pile1)malloc(sizeof(noeud1));
 if (temp !=NULL)
 { temp->val=v;

  temp->suivant=pil;
 }
 else
 {
  printf("nDebordement.");
  exit(1);
 }
 return(temp);

}

pile1 depiler1 (pile1 pil, long int &v)
{
 pile1 temp;

 if (pil==NULL)
 {
  printf("nPile vide.");
  exit(1);
 }
 else
 {
  v=pil->val;

  temp=pil;

  pil=pil->suivant;

  free(temp);

 }
 return(pil);
}

void top1 (pile1 pil, long int &v)
{
 if (pil==NULL)
 {
  printf("nPile vide.");
  exit(1);
 }
 else
  v=pil->val;

}

pile1 mettreazero1 (pile1 pil)
{

 pile1 temp;

 while (pil != NULL)
 {
  temp=pil;

  pil=pil->suivant;

  free(temp);
 }
 return(NULL);

}

int vide1 (pile1 pil)
{
 if (pil==NULL)
  return(1);
 else
  return(0);
}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.