Mi viene data una formula aritmetica contenente operatori +, -, *, / e parentesi (che potrebbero o non potrebbero cambiare la naturale precedenza degli operatori). Un esempio potrebbe essere il seguente: a / b + f â € "(c + d) * e â €" a * c. e mi viene chiesto di utilizzare uno stack (implementato come elenco collegato) per tenere traccia degli operandi e degli operatori: un esempio di come dovrebbe funzionare il mio programma è il seguente:
Il problema che ho difficoltà a capire è come posso distinguere la precedenza degli operandi !
Ecco una versione incompleta del codice che ho scritto:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct btnode Btree;
typedef struct node s_Node;
struct btnode {
char info;
Btree *left;
Btree *right;
};
struct node {
char element;
s_Node*next;
};
typedef struct{
s_Node *top_stack;
} stack_t;
int IsOperator(char c);
main () {
FILE* fp;
stack_t operands;
stack_t operators;
char c;
operands=NewStack();
operators=NewStack();
fp= fopen ("Myfile.txt", "r");
if (fp== NULL)
printf (" FILE COULD NOT BE OPENED");
else
{
c=getc(fp);
while (!feof (fp))
{
if ( c== ' ');
else
{
printf ("Here is your character: %c\n", c);
if (IsOperator (c))
Push (c, &operands);
else if ( isalpha (c))
}
c=getc(fp);
}
}
}
int IsOperator(char c)
{
switch(c)
{
case '+':
case '-':
case '/':
case '*':
return 1;
default:
return 0;
}
}
stack_t NewStack()
{
stack_t *n_stack;
n_stack=(stack_t*)malloc(sizeof(stack_t));
n_stack->top_stack=NULL;
return (*n_stack);
}
int Push(char e, stack_t *q)
{
s_Node *nn;
nn= (s_Node*)malloc(sizeof(s_Node));
if(Full(*q))
{
printf("\n\t Stack is Full !! \n\n");
return 0; // return 0 if enstack NOT successful
}
else
{
nn->element=e; // Storing the elemnt read inside the the new node
nn->next=q->top_stack; // Pointing the new node to the top of the stack
q->top_stack=nn; // Changing the top of the stack
return 1;
}
}
Grazie in anticipo!
per l'algoritmo che stai utilizzando, gli operandi non hanno precedenza. Ma in bottom-up shift-ridurre parser, ha la precedenza come @WhozCraig ha detto al commento di questo post qui sotto.
Gli operandi devono essere sempre inseriti nello stack degli operandi e verranno estratti 2 e calcolati con un operatore, quindi trasferiti nuovamente agli operandi come un unico operando.
Per la tua formula: a / b + f â € "(c + d) * e â €" a * c
push
alla pila di operandi operatore :
/
push
allo stack dell'operatore operatore : /
B
push
alla pila di operandi operatore : /
+
+
<= /
-> pop /, a & b -> a / b -> invia allo stack operand +
per impilare l'operatore operatore : +
f
operatore : +
-
-
<= +
-> pop +, (a / b) & f -> (a / b) + f -> push a pila degli operandi operatore : -
(
operatore : - (
c
operatore : - (
+
operatore : - (+
d
operatore : - (+
)
operatore : -
*
*
> -
premi allo stack dell'operatore operatore : - *
e
*
> -
push allo stack degli operandi operatore : - *
-
-
<= *
pop *, (c + d) & e -> (c + d) * e -> push allo stack operand -
<= -
pop -, ((a / b) + f) & ((c + d) * e) -> ((a / b) + f) - ((c + d) * e) -> push allo stack di operandi operatore : -
un
operatore : -
*
*
> -
premi allo stack dell'operatore operatore : - *
c
operatore : - *
fine della linea
risultato: ((((a / b) + f) - ((c + d) * e)) - (a * c))