• Calculator(1.5)


    Calculator(1.5)

    Github链接

    ps.负数的处理未完成

    解题过程中遇到的困难和解决

    1. <stack>的使用:

      认真研究了栈,基本上掌握了用法,与<queue>的区别就是队列中可以直接访问首元素而栈并不能。(debug过程让我深深体会到了使用s.pop()时一定要确认是否为空栈!!!!!)
    2. <sstream>的使用

      <sstream>用起来比较简单,网上查了资料就可以用了,注意点就是多次转化时要记得stream.clear,不然容易出错。
    3. 后缀表达式的转化及运算

      这次作业主要就是让我们理解前中后缀表达式吧...找到了一篇比较好理解的教程,总的过程比较长顺利,满足以下四个原则,照猫画虎地就转化了后缀表达式。

      转化原则

      • 当读到一个操作数时,立即将它放到输出中。操作符则不立即输出,放入栈中。遇到左圆括号也推入栈中。
      • 如果遇到一个右括号,那么就将栈元素弹出,将符号写出直到遇到一个对应的左括号。但是这个左括号只被弹出,并不输出。
      • 在读到操作符时,如果此时栈顶操作符优先性大于或等于此操作符,弹出栈顶操作符直到发现优先级更低的元素位置。除了处理')'的时候,否则决不从栈中移走'('。操作符中,'+' '-'优先级最低,'(' ')'优先级最高。
      • 如果读到输入的末尾,将栈元素弹出直到该栈变成空栈,将符号写到输出中。
    4. 命令行的使用

      依旧是找!资!料!掌握了新技能,开心。

    一点感想

    看到题目我就懵逼了,加上拖延症晚期,4.13才开始动手...总算把大部分写完了,还有个负数的情况还没搞定,过两天再填坑吧。感觉还是挺有成就感的,希望自己以后能勤快点吧...

    附上代码

    Calculation.cpp

    #include "Calculation.h"
    
    
    Calculation::Calculation()
    {
    
    }
    
    
    /*将Scan中的字符串传入*/
    void Calculation::GetQueue(queue<string>tmp)
    {
        Q = tmp; 
    }
    
    
    /*后缀转化是判断是否为括号*/
    bool isBr(string c)
    {
        if(c == "(" || c == ")")
    	    return 1;
        else 
    	    return 0;
    }
    
    
    /*确定运算符的优先级*/
    int getPri(string c)
    {
        if(c == "+" || c == "-")
    	    return 1;
        else if(c == "*" || c == "/")
    	    return 2;
        else if(c == "(" || c == ")")
    	    return 0; /*将括号的优先级设为最低防止误操作*/ 
    }
    
    
    /*根据运算符进行计算*/
    double Cal(char c , double a , double b)
    {
        switch(c)
        {
        case'+':return(a + b);break;
        case'-':return(a - b);break;
        case'*':return(a * b);break;
        case'/':return(a / b);break;
        }
    }
    
    
    /*后缀转化*/
    void Calculation::Change(queue<string>Q)
    {
        while(Q.size() != 0)
        {
    	    string c;
    	    c = Q.front();
    	
    	    /*处理运算符*/
    	    if(c == "+" || c == "-" || c == "*" || c == "/" || c == "(" || c == ")")
    	    {
    		
    		    /*传入括号时*/
    		    if(isBr(c))
    		    {
    			    /*左括号不做处理*/
    			    if(c == "(")
    			    {
    				    sym.push(c);
    			    }
    			    else
    			    {
    				    /*发现右括号时将栈顶元素弹出知道左括号,删除左括号*/
    				    while(sym.top() != "(")
    				    {
    					    get.push(sym.top());
    					    sym.pop();
    				    }
    				    sym.pop();
    			    }
    		    }
    		    /*传入其他运算符时*/
    		    else
    		    {
    			    /*根据运算符优先级进行弹出或传入*/
    			    while(sym.size() != 0 && getPri(c) <= getPri(sym.top()))
    			    {
    				    get.push(sym.top());
    				    sym.pop();
    			    }
    			    sym.push(c);
    		    }
    	    }
    	    /*数字直接传入*/
    	    else
    	    {
    		    get.push(c);
    	    }
    	    Q.pop();
        }
    
        /*Q为空栈时,将sym栈内所有运算符弹出*/
        while(sym.size() != 0)
        {
    	    get.push(sym.top());
    	    sym.pop();
        }
    }
    
    
    /*计算过程*/
    void Calculation::Ans()
    {
        std::stringstream stream;
        double tmp; 
        double a;
        stack<double>ans; /*存储运算值*/
    
        /*从队首元素开始进行计算*/
        while(get.size() != 0)
        {
    	    /*遇到数字直接转化为double类型入栈*/
    	    if(get.front()[0] >= '0' && get.front()[0] <= '9')
    	    {
    		    stream.clear();
    		    stream << get.front();
    		    stream >> tmp;
    		    ans.push(tmp);
    		    get.pop();
    	    }
    	    /*遇到运算符取出栈内两个数字进行运算后再入栈*/
    	    else
    	    {
    		    tmp = ans.top();
    		    ans.pop();
    		    a = Cal(get.front()[0] , ans.top() , tmp); /*Cal函数进行具体计算*/
    		    ans.pop();
    		    ans.push(a);
    		    get.pop();
    	    }
        }
        cout << ans.top() << endl; /*输出结果*/
    }
  • 相关阅读:
    开学考试学生成绩管理Java
    动手动脑问题1
    数据库的链接错误分析
    ASP.NET自定义错误页面
    php declare
    HTTP运行期与页面执行模型
    分部类(Partial Classes)
    ASP.NET:小编浅谈泛型的使用
    Windows 2003 SP2下安装IIS无法复制文件
    php 的include require 区别
  • 原文地址:https://www.cnblogs.com/zhengshuhao/p/5391516.html
Copyright © 2020-2023  润新知