中缀表达式转后缀表达式之多项式计算器

问题描述:输入一个多项式的表达式,要求得到计算后的结果。比如:输入3+(4+5)*2-5,输出结果0 。(什么,你居然说我没算对,你怕是有毒~~)

要求:1. 可以计算多位整数。比如2就是个位整数,234就是多位整数。

2. 满足带括号的要求

问题分析:给两个栈,一个存放数值,一个存放字符。用栈的方法把中缀表达式转换为后缀表达式:见链接这里写链接内容

然后从字符栈中出一个字符,从数值栈中出二个数字,进行运算再放入数值栈中,最后判断字符栈中是否还有元素,有就重复是上面的步骤,没有就输出数值栈的栈顶元素即可。

要点:1.所有的运算符都需要进行入栈操作

2.符号栈一旦出栈,必须进行运算

3.先在字符栈的栈底压入一个@,既方便思维又方便操作。

4.左括号直接入栈。当作符号的分割线!

#include<stdio.h>
#define MAX  50
int level(char p)  //规定运算符优先级
{
    int temp ;
    switch(p)
    {
        case '*':
        case '/':temp = 3;break;
        case '+':
        case '-':temp = 2;break;
        case '(':temp = 1;break;
        case '@':temp = -1;break;
    }
    return temp ;
}

void  cal(int number[] ,int *numberTop ,char Symbol[] ,int *SymbolTop) //从字符栈中取出一个字符,从数值栈中取出两个数值进行运算
{
    char operation = Symbol[(*SymbolTop)]; //出符号
    (*SymbolTop)--;
    int value1=number[(*numberTop)];
    (*numberTop)--;
    int value2=number[(*numberTop)];
    (*numberTop)--;
    int temp;
    switch(operation)
    {
        case '+':temp=value2+value1;  break;
        case '-':temp=value2 -value1; break;
        case '*':temp =value2*value1; break;
        case '/':temp =value2/value1; break;
    }
    (*numberTop)++;     //易错点!!!!!必须加括号!!!!!!
    number[*numberTop]=temp ;
}
int fun(char str[])
{
    char  Symbol[MAX];
    int SymbolTop= -1;  //运算符栈
    int numberTop= -1;  //数值栈
    int  number[MAX]; 
    int  y = 0; //用来计算多位数 
    int i= 0 ;
    Symbol[++SymbolTop]='@'; //先把 @ 入到符号栈中,就不用判断栈是否空了!!!这是一个比较聪明的想法
    while(str[i]){  //先遍历该字符串
        y= 0 ;
        if(str[i] <= '9' && str[i] >= '0'){ //是数字
            while(str[i] <= '9' && str[i] >= '0'){
                y= y*10+str[i]-'0' ;
                    i++;
            }
            number[++numberTop]=y ; //入栈数值
        } 
        else if((str[i] > '9' ||  str[i] < '0') && str[i] != '(' && str[i] != ')' ){   //不是数字,排除左,右括号的情况
            while(level(str[i]) <= level(Symbol[SymbolTop]))  //让栈中比它大的和等于它的都出栈!!!中缀表达式转后缀表达式的核心
                                                            //从符号栈中出一个符号,从数值栈中出两个数字,计算后压入数值栈
                    cal(number,&numberTop,Symbol,&SymbolTop);
            Symbol[++SymbolTop] = str[i];
            i++;
        }
        else if(str[i] == '('){   //遇见左括号直接入栈
            Symbol[++SymbolTop]='(';
            i++;
        }
        else if(str[i] == ')'){   //进行运算直到遇到左括号
            while(Symbol[SymbolTop] != '('){
               cal(number,&numberTop,Symbol,&SymbolTop);
            }
            SymbolTop--; //将左括号覆盖掉
            i++;
        }
    // 将Symbol 栈检查一下,返回number 的栈顶,结束
    }
   while(Symbol[SymbolTop] != '@'){
            cal(number,&numberTop,Symbol,&SymbolTop);
   }
    return number[numberTop];
}
int main(void)
{
    char str[MAX];
    int result ;
    printf("Please input the str (please sure it right)\n");
    gets(str);
    printf("You input is %s \n",str);
    result=fun(str);
    printf("result = %d \n",result);
    return 0;
}

运行截图:

这里写图片描述

题后反思:1. 如果用户输入的多项式表达式错误该如何处理?

2. 如果输入的不仅仅是整数,而是实数该如何处理?

关于C语言知识的一点补充:

为什么是 (*numberTop)++,而不*numberTop++?

解答:因为我们需要在函数cal 中改变numberTop的值(让它减一),所以我给他传入了他的指针。那么如何在调用的函数中让他减一呐?查阅 ++ 的运算优先级是要高于 * 的优先级的,而我们的目的是改变它在原函数中的值,那么我们就得先用括号把(*numberTop)括起来,再给它减一!!!!

posted @ 2017-10-25 22:03  Tattoo_Welkin  阅读(198)  评论(0编辑  收藏  举报