snakers07
Messages postés15Date d'inscriptionvendredi 14 novembre 2008StatutMembreDernière intervention24 octobre 2009
-
15 mai 2009 à 09:57
cptpingu
Messages postés3840Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention23 août 2024
-
26 mai 2009 à 19:40
bonjour, j'ai crée un programme permettant de calculer une formule utilisant les opérateurs +,-,*,/
avec un controle sur les parenthése:
par exemple :
((5-4)-(3*4))=-11
le probleme est que je suis obligé à chaque fois de parenthéser complétement mon expression.
je voudrais avoir ceci:
avant: ((5-4)-(3*4))=-11
après: (5-4)-(3*4)=-11 j'aimerai que en écrivant cette formule sous cette forme, qu'il me donne le même résulat
void initialiserNum(NumLifo* lifo){
//initialisation des valeurs de la pile
int i=0;
for(i=0;i<50;i++){
lifo->pile[i]=0; //lifo->pile[i] est equivalent à *lifo.pile[i]
}
//initialisation du sommet
lifo->sommet=-1;
}
int empilerNum(NumLifo* lifo, double value){
//test de position du sommet
if(lifo->sommet < 49){
lifo->sommet++; //incrémentation du sommet
lifo->pile[lifo->sommet] = value; //enregistrement de la valeur
return 1;
}else{
return 0;
}
}
double depilerNum(NumLifo* lifo){
double value=0; //test de position du sommet
if(lifo->sommet > -1){
value = lifo->pile[lifo->sommet]; //récupération temporaire de la valeur
lifo->pile[lifo->sommet] = 0; //mise à zéro de la valeur courante
lifo->sommet--; //décrémentation du sommet
return value;
}else{
return 0;
}
}
void afficherNum(NumLifo* lifo){
int i=0;
printf("\n");
for(i=0;i<=lifo->sommet;i++){
printf("%d\t%f\n",i,lifo->pile[i]);
}
printf("Sommet %d\n",lifo->sommet);
}
void initialiserChar(CharLifo* lifo){
//initialisation des valeurs de la pile
int i=0;
for(i=0;i<50;i++){
lifo->pile[i]='\0';
}
//initialisation du sommet
lifo->sommet=-1;
}
int empilerChar(CharLifo* lifo, char value){
//test de position du sommet
if(lifo->sommet < 49){
lifo->sommet++; //incrémentation du sommet
lifo->pile[lifo->sommet] = value; //enregistrement de la valeur
return 1;
}else{
return 0;
}
}
char depilerChar(CharLifo* lifo){
char value = '\0';
//Test de position du sommet
if(lifo->sommet > -1){
value = lifo->pile[lifo->sommet]; //récupération temporaire de la valeur
lifo->pile[lifo->sommet] = 0; //mise à zéro de la valeur courante
lifo->sommet--; //décrémentation du sommet
return value;
}else{
return 0;
}
}
void afficherChar(CharLifo* lifo){
int i=0;
printf("\n");
for(i=0;i<=lifo->sommet;i++){
printf("%d\t%c\n",i,lifo->pile[i]);
}
printf("Flag %d\n",lifo->sommet);
}
/*-----
Calcul
-----*/
double calcul(char* expression){
//Déclarations
char* c=NULL; //pointeur qui parcourt le tableau (plus facile que naviguer dans celui-ci)
int OpenParenthese = 0; //définit si la derniére occurance été une parenthése ouvrante : seul cas possbile pour un nombre négatif
NumLifo numbers; //pile des nombres
CharLifo operations; //pile des opérations
initialiserNum(&numbers);
initialiserChar(&operations);
//Parcours de l'expression
for(c=expression; c<expression+strlen(expression); c++){
//Détection d'un nombre
if( (*c>='0' && *c<='9') || (*c=='-' && OpenParenthese==1) ){
char* end; //poiteur de fin de chaine du nombre
double number;
//récupération du nombre
number=strtod(c,&end); /*fonction qui convertie une portion de chaine en double (ex: 2 chiffres a la suite en nombre)
chercher sur internet pour faciliter les calculs parce que sinon trop incomprehensible*/
empilerNum(&numbers,number);
//mise à jours des variables
c=end-1;
OpenParenthese=0;
continue;
}
Quelques remarques sur le code:
for(c=expression; c<expression+strlen(expression); c++)
Et pourquoi pas tout simplement ceci, qui est plus rapide d'ailleurs:
for (char* c = expression; c && *c; c++)
Ou si tu préfères, en plus explicite:
for (char* c = expression; c != NULL && *c != '\0'; c++)
Voici toutefois une version qui fonctionne, que j'ai un peu "proprisé" en passant (et corriger 2-3 petits trucs). Ton problème venait du fait que tu ne te servait jamais de "OpenParenthese". A noter que c'est plus de la bidouille sale fait à la va-vite, qu'autre chose. Renseigne toi sur une vraie méthode pour répondre à ce besoin: les AST.
snakers07
Messages postés15Date d'inscriptionvendredi 14 novembre 2008StatutMembreDernière intervention24 octobre 2009 26 mai 2009 à 17:46
merci beaucoup de ton aide, j'ai modifié ton code et il marche bien, j'ai du rajouter quelques conditions, mais rien de bien méchant.
maintenant j'aimerai te poser une dernière question, à savoir les priorité
c'est à dire si j'effectue le calcul suivant:
(4-1*9)+(9*5)= 44
en bref de gérer la priorité sur la multiplication vis a vis de la soustraction
cptpingu
Messages postés3840Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention23 août 2024126 26 mai 2009 à 19:40
Gérer ce type de priorité est bien plus hardu. Il faudrait revoir beaucoup de chose dans ton code pour gérer cela correctement (comme je te l'ai dit, la version que je te propose est sale).
Plutôt que de bidouiller ton code, je te conseil de jeter un coup d'oeil à ce qu'on appelle les AST, ainsi qu'à la grammaire en notation BNF.
Mieux vaut utiliser une méthode propre, maintenable et élégante, plutôt que de t'empêtrer sur une successions de bidouille.