2013-05-04 1 views
1

Я по-прежнему новичок и не слишком быстро собираю код с C. Для назначения мне нужно оценить выражение Postfix из массива с использованием стека. Хотя я уверен, что у меня есть несколько проблем с моим кодом, я чувствую, что основная структура хороша. Он компилируется без ошибок, но имеет некоторые предупреждения. Он будет запускать и распечатывать заявления printf в главном меню, но я не буду ничего делать в оценке, насколько я могу судить. Я не ищу чит или полное исправление, но некоторые рекомендации будут оценены Пожалуйста, ответьте, предполагая, что я знаю очень мало.Оценить постфиксное выражение с использованием стека и массива в C

Приветствия

#include <stdio.h> 
#include <stdlib.h> 

struct stackNode { 
    int data; 
    struct stackNode *nextPtr; 
}; 
typedef struct stackNode StackNode; 
typedef StackNode *StackNodePtr; 

int evaluatePostfixExpression(char *expr); 
int calculate(int op1, int op2, char operator); 
void push(StackNodePtr *topPtr, int value); 
int pop(StackNodePtr *topPtr); 
int isEmpty(StackNodePtr topPtr); 
void printStack(StackNodePtr topPtr); 

char postfix[50]; 
int answer; 



void main() 
{ 
    printf("Print an postfix expression\n"); 
    scanf("%s", postfix); 
    evaluatePostfixExpression(postfix); 
    printf("The value of the expression is: %i",answer); 
} 

int evaluatePostfixExpression(char *expr) 
    //Evaluate the postfix expression. 
{ 

    StackNode node; 
    StackNodePtr ptrnode; 
    ptrnode = &node; 

    int x; 
    int y; 
    int z; 

    strcat(ptrnode,'\0');/*Append the null character ('\0') to the end of the postfix expression. 
    When the null character is encountered, no further processing is necessary.*/ 

    int i=0; 
    for(i; postfix[i]!='\0'; i++){  //While '\0' has not been encountered, read the expression from left to right. 
     if(isdigit(postfix[i])){   //If the current character is a digit,Push its integer value onto the stack 
      push(&ptrnode, postfix[i]); //(the integer value of a digit character is its value in the computer’s character 
      printStack(ptrnode);       //set minus the value of '0' in the computer’s character set). 
     } 
     else if(postfix[i]=='+'||postfix[i]=='-'||postfix[i]=='*'||postfix[i]=='/'||postfix[i]=='^'){     //Otherwise, if the current character is an operator, Pop the two top elements of the stack into 
      x=pop(&ptrnode); //variables x and y. Calculate y operator x. 
      printStack(ptrnode); 
      y=pop(&ptrnode); 
      printStack(ptrnode); 
      z=calculate(x,y,postfix[i]); 
      push(&ptrnode, z);   /*Push the result of the calculation onto the stack.*/ 
      printStack(ptrnode); 
     } 
     if (postfix[i]=='\0'){ //When the null character is encountered in the expression, pop the top value of the 
      answer = pop(&ptrnode);//stack. This is the result of the postfix expression. 
      printStack(ptrnode); 
     } 
    } 
} 

int calculate(int op1, int op2, char operator) 
    //Evaluate the expression op1 operator op2. 
{ 
    if (operator=='+') 
     return op1+op2; 

    else if (operator=='-') 
     return op1-op2; 

    else if (operator=='*') 
     return op1*op2; 

    else if (operator=='/') 
     return op1/op2; 

    else if (operator=='^') 
     return op1^op2; 



    else{ 
    return printf("calculation error"); 
    } 
} 

void push(StackNodePtr *topPtr, int value) 
    //Push a value on the stack. 
{ 
    StackNodePtr temp; /* to create a new node */ 
    temp = malloc(sizeof(value));//need Malloc because it will not remember it 
    temp->data = value; 
    temp->nextPtr = NULL; /* the new node points to NULL */ 


    if(isEmpty(*topPtr)==0) { 
    temp->nextPtr = *topPtr; 
    } 

} 

int pop(StackNodePtr *topPtr) 
    //Pop a value off the stack. 
{ 
    char Data ; /* to be used to store the data */ 
    StackNodePtr tmp; /* to be used for handling the node*/ 
         /* that is going to be deleted */ 
    tmp = *topPtr; /* tmp has the address of the node */ 
         /* that is going to be deleted */ 
    Data = tmp->data; 
    *topPtr = tmp->nextPtr; 

    free(tmp); 
    return Data; 
} 

int isEmpty(StackNodePtr topPtr) 
    //Determine if the stack is empty. 
{ 
    if(topPtr->nextPtr==NULL) 
     return 1; 
    else 
     return 0; 
} 

void printStack(StackNodePtr topPtr) 
    //Print the stack. 
{ 
    while ((topPtr->nextPtr)!=NULL){ 
     printf("%C",topPtr->data); 
    } 
    if ((topPtr->nextPtr)==NULL) 
     printf("NULL"); 

    printStack(topPtr->nextPtr); 
} 
+0

В 'main', для чтения строки с использованием' scanf' используйте ''% ''вместо' '&'' as, 'scanf ("% s ", postfix);' – Rohan

+0

'postfix [i] == ('+') | ('-') | ('*') | ('/') | ('^') 'один за другим – BLUEPIXY

+0

Конечно, спасибо, я пропустил это – OverusedUser

ответ

5

Одна вещь, которую я мог видеть сразу был:

if(postfix[i]=="%i"){ //If the current character is a digit,Push its integer value onto the stack 

Это неправильно. Вы сравниваете символ в индексе i с адресом строкового литерала. Вместо этого вы должны использовать функцию isdigit().

Также

else if(postfix[i]==('+')|('-')|('*')|('/')|('^')){ 

должно быть:

else if(postfix[i]=='+' || postfix[i]=='-' || ..... 
+0

Спасибо за помощь. Я вижу, где я совершил эти ошибки. Однако теперь после этого изменения он не завершит программу. как будто он застревает в цикле, но не падает. Я попытался использовать отладчик, чтобы найти, где он идет не так, но не может найти его. – OverusedUser

-1
/* Here is the best example for evaluating postfix expression */ 
    /* 8+(7-9)*2 */ 
    #include<stdio.h> 
    #include<conio.h> 
    #include<string.h> 
    #define Max 20 
    #include <ctype.h> 
    #define SIZE 50   /* Size of Stack */ 
    int s[SIZE]; 

    int TOS=-1,TOP=0; 
    int top=-1;  /* Global declarations */ 

    char infix[Max],post[Max],stack[Max]; 
    void push(char); 
    void infix_post(); 
    char pop(); 
    int precedence(char ch); 
    void main() 
    { 
    clrscr(); 
    printf("\n enter the expression "); 
    fflush(stdin); 
    gets(infix); 
    strcat(infix,")"); 
    infix_post(); 
    printf("\n Postfix exp. is ::>> %s",post); 
    postfix_convert(post); 
    getch(); 
    } 
    void infix_post() 
    { 
     int i=0; 
     char temp; 
     push('('); 
     while(infix[i]!='\0') 
     { 
      if(isdigit(infix[i])) 
      { 
    post[TOP++]=infix[i]; 
      } 
      else 
      { 
    switch(infix[i]) 
    { 
     case '(': 
    push(infix[i]); 
    break; 
     case ')': 
    temp=pop(); 
    while(temp!='(') 
    { 
     post[TOP++]=temp; 
     temp=pop(); 
    } 
    break; 
     case '+': 
     case '-': 
     case '*': 
     case '/': 
     case '%': 
     case '$': 
     case '^': 
      while(precedence(infix[i])<=precedence(stack[TOS])) 
      { 
     temp=pop(); 
     post[TOP++]=temp; 
      } 
      push(infix[i]); 
      break; 

     default: 
     break; 
    } // switch 

      }// else 
     i++; 
     } // while 
     post[TOP]='\0'; 
    }// main 
    void push(char ch) 
    { 

     if(TOS==Max-1) 
     { 
     printf("\n overflow"); 
     getch(); 
     return; 
     } 
     else 
     { 
     stack[++TOS]=ch; 
     } 
    } 
    char pop() 
    { 
     if(TOS==-1) 
     { 
     printf("\n underflow"); 
     return -1; 
     } 
     else 
     return(stack[TOS--]); 
    } 

    int precedence(char ch) 
    { 
     if(ch=='+'||ch=='-') 
     return 1; 
     else if(ch=='%'||ch=='/'||ch=='*') 
     return 2; 
     else if (ch=='$'||ch=='^') 
     return 3; 
     else 
     return 0; 
    } 
    push_p(int elem) 
    {      /* Function for PUSH operation */ 
     s[++top]=elem; 
    } 

    int pop_p() 
    {      /* Function for POP operation */ 
     return(s[top--]); 
    } 

    postfix_convert(char pofx[Max]) 
    {       /* Main Program */ 
     char ch; 
     int i=0,op1,op2; 
     printf("\n\n Postfix Expression ? %s",pofx); 
     while((ch=pofx[i++]) != '\0') 
     { 
    if(isdigit(ch)) 
    push_p(ch-'0'); /* Push the operand */ 
    else 
    {  /* Operator,pop two operands */ 
     op2=pop_p(); 
     op1=pop_p(); 
     switch(ch) 
     { 
     case '+':push_p(op1+op2);break; 
     case '-':push_p(op1-op2);break; 
     case '*':push_p(op1*op2);break; 
     case '/':push_p(op1/op2);break; 
     } 
    } 
     } 
     printf("\n Given Postfix Expn: %s\n",pofx); 
     printf("\n Result after Evaluation: %d\n",s[top]); 
    } 
0

Обычная логика оценки экспрессии после исправления по стеку может решить только число 1 цифра т.е. 0-9. Это очень большой недостаток используемой логики, а также делает программу практической. Путем простого изменения метода ввода в стек мы устранили проблему одиночного целого числа цифр, и теперь для оценки может использоваться ряд цифр. Получить код: http://wowmoron.wordpress.com/2014/11/16/evaluation-of-postfix-expression-containing-multi-digit-integer/

0

Это link, чтобы решить вашу проблему после выражения выражения.