使用C中的堆栈和数组计算后缀表达式

时间:2013-05-04 09:51:24

标签: c postfix-notation

我仍然是新手,并且不太快就用C来获取编码。对于一项任务,我必须使用堆栈来评估数组中的Postfix表达式。虽然我确信我的代码有几个问题但我觉得基本结构很好。它编译没有错误,但确实有一些警告。它将在main中运行并打印出printf语句,但据我所知,它不会在评估中做任何事情。 我不是在寻找作弊或完整的解决办法,但我会不胜感激 请回答假设我知之甚少。

干杯

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

4 个答案:

答案 0 :(得分: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]=='-' || ..... 

答案 1 :(得分:0)

通过堆栈评估后固定表达式的传统逻辑可以解决仅1位数的数字,即0-9。这是所使用的逻辑的一个非常大的缺点,并且它使得该程序没有实际用途。通过简单地改变输入到堆栈的方法,我们已经消除了单个数字整数的问题,现在可以使用任何数字的数字进行评估。 获取代码:http://wowmoron.wordpress.com/2014/11/16/evaluation-of-postfix-expression-containing-multi-digit-integer/

答案 2 :(得分:0)

这是解决后缀表达式评估问题的link

答案 3 :(得分:-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]);
    }