关于Calculator的第四次作业

一、魔法传送门:

问题描述:点我点我点我!
仓库地址:点我点我点我!

二、网上资料:

sstream的介绍及应用
后缀表达式C++代码
中缀转前缀及后缀方法
C++计算器源代码

三、实现过程:

在看到题目之后,说实在的就是一脸懵逼,完全不知道从哪里下手,后来在泡泡老师(浩晖犇犇)的提醒下,了解到了中缀改后缀计算其值的方法,于是便有了以上的资料链接,看完之后,脑袋完全是懵逼的状态,但是缕清了思路之后,自己便尝试去按照介绍的方法去试着打出代码,打完之后,对于简单的式子比如(1+2、3+4等)中缀能变换成后缀,但是复杂的式子就不行了,后来在泡泡老师的指导下,debug之后才发现是括号优先级处理出了问题,废话不多说,上代码:
这里只列Calculator.cpp的代码:

/****************************************
栈:sign用来存取运算符;
    opr用来存取操作数;    
    rpn用来存取后缀表达式; 
    num用来存取整型数据;
数组:mark:标记符号优先级; 
函数:sstream用来操作字符串类型与整型字符型的转化;
      clear  用来清除多次使用的sstream对象;     
****************************************/
#include "calculation.h"
#include <iostream>
#include <sstream>
#include <queue>
#include <stack>

using namespace std;

Calculation::Calculation()
{
    error = false;
}

Calculation::~Calculation()
{
}

//------------------------------------------------------
    stack<string>sign; 
    stack<string>opr;
    stack<string>rpn;
//------------------------------------------------------
void Calculation::Getqueue(string input)
{
    
    //初始化-------------------------------------- 
    int mark[50];
    mark['+'] = 1;
    mark['-'] = 1;
    mark['*'] = 2;
    mark['/'] = 2;
    mark[')'] = 3;
    mark['('] = 4;  
    Scan s1;
    queue<string> tmp1 = s1.ToStringQueue(input);
    //-------------------------------------------- 
    //1.中缀转后缀---------------------------------
    if (s1.IsError() == false)
    {
        if (tmp1.front() == "-")
        {
            opr.push("0");
        } 
        while ( tmp1.empty() == false )
        {
            //---1.处理操作数
            if ( tmp1.front()[0] >= '0' && tmp1.front()[0] <= '9')
            {
                opr.push( tmp1.front() );
                tmp1.pop();
            }
            //---2.处理运算符
            else
            {
                if ( sign.empty() == true || sign.top() == "(")  
                {
                    sign.push( tmp1.front() );
                    tmp1.pop();
                    continue;               
                }
                  
                //运算符栈非空
                //----1.判断括号的匹配 
                if ( tmp1.front() == ")" )
                {
                    while ( sign.top() != "(")
                    {
                        opr.push( sign.top() );
                        sign.pop();
                    }
                    tmp1.pop();
                    sign.pop(); 
                }
                //----2.判断优先级
                else 
                {
                    
                    for ( ; sign.empty() == false && sign.top()!= "("  
                                    && (mark[tmp1.front()[0]] <= mark[sign.top()[0]]); )
                    {
                        opr.push( sign.top() );
                        sign.pop();
                    }
                    sign.push( tmp1.front() );
                    tmp1.pop();
                }
            }
        }
        //----3.处理剩余的运算符 
        while ( sign.empty() == false ) 
        {
            if (sign.top() == "(" || sign.top() == ")")
            { 
                sign.pop();
            }
            else
            {   
                opr.push( sign.top() );
                sign.pop();
            }
        }
        
        while (opr.empty() == false)
        {
            rpn.push( opr.top() );
            opr.pop();
        }
    
        //4.开始计算啦
        //初始化--------------------- 
        stringstream stream;
        double n,a,b;
        stack<double>num;
        //---------------------------
        while ( rpn.empty() == false)
        {
            if ( rpn.top()[0] >= '0' && rpn.top()[0] <='9')
            {
                stream << rpn.top();
                stream >> n;
                num.push(n);
                stream.clear();
                rpn.pop(); 
            }
            else
            {
                a = num.top();
                num.pop();
                b = num.top();
                num.pop();
                if (rpn.top() == "+")
                {
                    num.push(b+a);
                    rpn.pop();
                }
                else if (rpn.top() == "-")
                {
                    num.push(b-a);
                    rpn.pop();
                }
                else if (rpn.top() == "*")
                {
                    num.push(a*b);
                    rpn.pop();  
                }
                else
                {
                    //除数为0时的处理 
                    if ( a==0 )
                    {
                        error = true;
                        num.push(0);
                        rpn.pop(); 
                    }
                    else
                    {
                        num.push((double)b/a);
                        rpn.pop();
                    }
                } 
            }
        }
        
        if ( error == true)
        { 
            cout << "Error" << endl;
        } 
        else
        { 
            cout << num.top() << endl; 
        }
    } 
}
         

1.测试结果:

885520-20160413113101145-1277202759.png
885520-20160413113049582-1443017511.png
除数为0的处理

2.一些方法:

对于类似-24+35……开头为负数的式子,可以提前在存储操作数的栈中push(0);对于除数为0的处理也可以push(0)作为运算结果或者continue掉,在最后输出的时候判断是否出现判0的情况来决定是输出正确答案还是输出Error;

四、总结与感受:

针对于第四次作业,发觉自己在对问题处理上还不够细致,想法还不够简练,导致码出来的代码过于复杂,这里需要多多锻炼,debug的能力还待加强。学会了sstream的用法及对栈 (讲道理,有福利!<--栈的经典运用)有了初步的了解,对cmd命令也有了初步的了解点这里!,学无止境,希望自己在学习的道路上越走越远!

转载于:https://www.cnblogs.com/distances/p/5351822.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值