Calculatrice en C à l'aide de la pile
Je suis en train de créer une calculatrice en c qui permet de calculer la priorité et obtenir de bons résultats pour des exemples comme ceux-ci:
((5+5)/3)*3) -- > 9
((1+2) * 3) -- > 9
Ces exemples mon code ci-dessous peut calculer. Mais pour quelque chose comme ça
(2+5) * (2+5)
, mon programme donne la mauvaise réponse.
Je suis à l'aide de 2 piles. L'un pour les opérateurs et un pour les nombres. Il fonctionne sur ce principe:
suit:
((4 - 2) * 5) + 3
--> normal infix expression:
+ * - 4 2 5 3
Pseudo-code:
Read + (an operation), push it onto the stack,
Read * (an operation), push it onto the stack,
Read - (an operation), push it onto the stack,
Read 4 (a number), the top of the stack is not a number, so push it onto the stack.
Read 2 (a number), the top of the stack is a number, so pop from the stack twice, you get 4 - 2, calculate it (2), and push the result (2) onto the stack.
Read 5 (a number), the top of the stack is a number, so pop from the stack twice, you get 2 * 5, push the result (10) onto the stack.
Read 3 (a number), the top of the stack is a number, so pop from the stack twice, you get 3 + 10, push the result (13) onto the stack.
Nothing left to read, pop from the stack and return the result (13).
Code:
#include <stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 102
typedef struct
{
char stk[MAXSIZE];
int top;
}STACK;
typedef struct stack
{
int stk[MAXSIZE];
int itop;
}INT_STACK;
STACK s;
INT_STACK a;
void push(char);
char pop(void);
void display(void);
int main()
{
a.itop = 0;
char string[MAXSIZE],vyb,vyb2;
int cislo1,cislo2,vysledok;
while (gets(string) != NULL){
for(int j = strlen(string); j > 0; j--){
if(string[j] == '*' || string[j] == '/' || string[j] == '+' || string[j] == '-')
push(string[j]);
}
//display();
for(int j = 0; j < strlen(string); j++){
if(isdigit(string[j])&&!(a.itop)){
//display();
char pomoc[2];
pomoc[0] = string[j];
pomoc[1] = '\0';
int_push(atoi(pomoc));
}
else if(isdigit(string[j])&&(a.itop)){
cislo1 = int_pop();
vyb2 = pop();
char pomoc[2];
pomoc[0] = string[j];
pomoc[1] = '\0';
cislo2 = atoi(pomoc);
if(vyb2 == '+')
vysledok = cislo1+cislo2;
else if(vyb2 == '-')
vysledok = cislo1-cislo2;
else if(vyb2 == '*')
vysledok = cislo1*cislo2;
else if(vyb2 == '/')
vysledok = cislo1 / cislo2;
//printf(" v %d",vysledok);
int_push(vysledok);
}
}
printf("%d\n",int_pop());
}
}
/* Function to add an element to the stack */
void push (char c)
{
s.top++;
s.stk[s.top] = c;
//printf ("pushed element is = %c \n", s.stk[s.top]);
}
/* Function to delete an element from the stack */
char pop ()
{
char num = s.stk[s.top];
//printf ("poped element is = %c\n", s.stk[s.top]);
s.top--;
return(num);
}
int empty()
{
if (s.top == - 1)
{
printf ("Stack is Empty\n");
return (s.top);
}
return 1;
}
void display ()
{
int i;
if (!empty)
{
printf ("Stack is empty\n");
return;
}
else
{
printf ("\n The status of the stack is \n");
for (i = s.top; i >= 0; i--)
{
printf ("%c\n", s.stk[i]);
}
}
printf ("\n");
}
void int_push (int c)
{
a.itop++;
a.stk[a.itop] = c;
//printf ("pushed element is = %d \n", a.stk[a.itop]);
}
/* Function to delete an element from the stack */
int int_pop ()
{
int num = a.stk[a.itop];
//printf ("poped element is = %d\n", a.stk[a.itop]);
a.itop--;
return(num);
}
Est-il un autre moyen de créer une calculatrice avec priorité, ce qui peut donner de bonnes réponses?
Merci pour votre répondre
Une meilleure approche serait d'utiliser postfix notation. Cela nécessitera une pile(pour les opérandes de l'opérateur ou selon votre souhait). Le calcul dans postfix notation est trivial alors.
Comment est (2+5)(2+5) une expression valide?
manque un astérisque ai interprété comme Markdown pour italique.
Mauris est à droite, il y a un manque d'asterisk, car il est certain symbole spécial ici
Votre code ne reconnaît pas les parenthèses dans la chaîne d'entrée, il l'ignore complètement et ne pas manipuler d'une quelconque façon. C'est pourquoi votre calculatrice n'est que de mal. En fait, il semble impossible de calculer
Comment est (2+5)(2+5) une expression valide?
manque un astérisque ai interprété comme Markdown pour italique.
Mauris est à droite, il y a un manque d'asterisk, car il est certain symbole spécial ici
Votre code ne reconnaît pas les parenthèses dans la chaîne d'entrée, il l'ignore complètement et ne pas manipuler d'une quelconque façon. C'est pourquoi votre calculatrice n'est que de mal. En fait, il semble impossible de calculer
3-(2-1)
.
OriginalL'auteur Jozef Bugoš | 2015-06-28
Vous devez vous connecter pour publier un commentaire.
Mettre des points d'arrêt - vous aurez l'expression suivante:
+ + * 2 5 2 5
. Le problème avec cela, c'est votre interprète est interpeting ce que(2+5+2)*5
au lieu de(2+5) * (2+5)
.Eh bien, vous demandez peut-être comment résoudre ce problème. Il n'y a pas de simple solution unique - vous pouvez soit fixer votre propre interprète, ou de construire une toute nouvelle mécanique de jeu, parce que la façon de construire les expressions ne peuvent tout simplement pas gérer plus d'une paire de parthesises.
Par exemple, vous pouvez calculer toutes les valeurs de la parnthesises avant même la construction de l'expression seperatley, éventuellement en utilisant la récursivité dans le cas de parenthesiseception - toutefois, si vous choisissez d'utiliser cette méthode, vous pouvez changer la façon de travailler avec les expressions entièrement, parce que c'est une approche différente.
Si vous avez besoin de moi pour montrer de réels exemples de code pour expliquer cette plus loin à l'aide de certaines parties du code que vous avez fait, il suffit de demander pour elle et je vais modifier et de fournir ce dont vous avez besoin.
De toute façon, j'ai vraiment vous conseillons de rechercher de travail avec des interprètes en général - on peut vraiment apprendre beaucoup de choses sur l'analyse des chaînes de caractères et de travail avec des entrées différentes, et même les gens qui ne les trucs similaires à la vôtre avec des calculatrices avant
MODIFIER: vous demandé des exemples, si vous pouvez y aller - c'est un exemple d'une méthode complètement différente en utilisant la récursivité. De cette façon, vous permet de gérer une seule paire de parenthesises à un moment, et ainsi vous n'aurez pas le problème, vous ne le font actuellement. Remarque - la source, je suis en la fondant sur des ( assez bien copier-collé avec les modifications de fil et quelques commentaires personnels ) est de codereview sur stack exchange, vous pouvez le voir, il ici
si vous êtes intéressé.
Vous voudrez peut-être regarder à mon montage. Si vous avez des doutes, n'hésitez pas à demander ou chercher à la source mentionnée.
Merci, j'ai essayé cette méthode, mais je ne pouvais pas faire droit à cette époque, alors maintenant que j'ai essayé une autre méthode. Je vais regarder le code que vous l'avez édité.
Essayez de rechercher Shunting-yard algorithme (ici, DONC, et dans Wikipedia).
OriginalL'auteur A. Abramov