简体   繁体   中英

Evaluate a postfix expression using a stack and array in C

I am still new and not too quick on picking up coding with C. For an assignment I have to evaluate a Postfix expression from an array using a stack. While I am sure I have several problems with my code I feel the basic structure is good. It compiles without errors, but does have some warnings. It will run and printout the printf statements in main but will not do anything in the evaluation as far as I can tell. I am not looking for a cheat or a complete fix but some guidance would be appreciated Please respond assuming I know very little.

Cheers

#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);
}

One thing I could see immediately was:

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

This is incorrect. You are comparing the character at index i with the address of the string literal. You should be using a function like isdigit() instead.

Also

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

should be:

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

Conventional logic of evaluation of post-fix expression by stack can solve numbers of only 1 digit ie 0-9. This is a very big drawback of the logic used as well as it makes the program of no practical use. By simple change in the method of input into the stack we have removed the problem of single digit integer and now a number of any digit might be used for evaluation. Get the code: http://wowmoron.wordpress.com/2014/11/16/evaluation-of-postfix-expression-containing-multi-digit-integer/

这是一个解决你的后缀表达式评估问题的链接

/* 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]);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM