zoukankan      html  css  js  c++  java
  • 中缀表达式转后缀表达式之多项式计算器

    问题描述:输入一个多项式的表达式,要求得到计算后的结果。比如:输入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)
    ");
        gets(str);
        printf("You input is %s 
    ",str);
        result=fun(str);
        printf("result = %d 
    ",result);
        return 0;
    }
    
    

    运行截图:

    这里写图片描述

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

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

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

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

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

  • 相关阅读:
    JVM底层原理 内存模型+GC垃圾回收
    新Socket与网络小结
    Redis五大数据结构及基本指令用法
    MySql高级汇总-事务,索引,SQL调优,分库分表,读写分离
    笔试错题整理
    设计模式(思路)
    网络编程
    linux
    基础算法--KMP匹配字符串
    基础算法--整数二分
  • 原文地址:https://www.cnblogs.com/Tattoo-Welkin/p/10335322.html
Copyright © 2011-2022 走看看