关于Calculator的第四次作业

一、魔法传送门:

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

二、网上资料:

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

三、实现过程:

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

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

using namespace std;

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

Calculation::~Calculation()
{
}

//------------------------------------------------------
stacksign;
stackopr;
stackrpn;
//------------------------------------------------------
void Calculation::Getqueue(string input)
{

//初始化--------------------------------------
int mark[50];
mark['+'] = 1;
mark['-'] = 1;
mark['*'] = 2;
mark['/'] = 2;
mark[')'] = 3;
mark['('] = 4;
Scan s1;
queue 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;
stacknum;
//---------------------------
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.测试结果:



除数为0的处理

2.一些方法:

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

四、总结与感受:

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

posted @ 2016-04-13 12:00  Distances  阅读(245)  评论(3)    收藏  举报