程序设计第四次作业——计算器第二步(计算)
Github 链接:https://github.com/luojingzhao/object-oriented/tree/master/calculate
本次作业要求
<1>使用调用的方式。也就是在命令行里(如windows下的cmd)输入表达式,得到结果。
<2>对四则运算表达式进行拆解。
<3>通过两个栈来处理计算和优先级。
开始
从看到题目就是一脸懵逼,后来看了同学的博客和在网上相关的资料的查找,才渐渐了解的题目的大概意思,和主要的如何实现目的的代码操作。
想法:
<1>将队列传入处理的函数calculate,扫描并划分哪一些是操作符,哪些是计算数;
<2>通过优先级,来处理操作符push进栈的先后;
具体实现
<1>创建两个栈,分别用来存储操作符和数字
stack<string> StaOper; //只处理+ - # / ()运算
stack<double> StaNum; //只处理输入数字运算
<2>判断是否是操作数还是数字
bool Operation::Isoperator(string str)
{
if(str == "+" || str == "-" ||
str == "*" || str == "/" ||
str == "(" || str == ")" || str == "#")
return true;
else
return false;
}
<3>主要的难点是操作符优先级的判断,这个我想了很久也不会,于是查找了网上相关的资料
了解到计算机是无法自己识别括号,并像人工那样计算的,只能将中缀表达式转变为后缀表达式,以栈的方式进行读取计算。
Operation::Operation() //定义构造函数为数据赋值
{
OprRelation[0] = ">><<<>>"; // '+'
OprRelation[1] = ">><<<>>"; // '-'
OprRelation[2] = ">>>><>>"; // '*'
OprRelation[3] = ">>>><>>"; // '/'
OprRelation[4] = "<<<<<= "; // '('
OprRelation[5] = ">>>> >>"; // ')'
OprRelation[6] = "<<<<< ="; // '#'
}
虽然借鉴了,但是主要的意思,就是这个优先级的判断是如何得来的,还是搞不太清楚
<4>栈的存储都完成后,最后只要取出一个操作符和两个数字进行计算就可以了。
遇到的困难
<1>在传入的队列多了一个回车(这个bug让我找了很久,一直是带有括号的计算不了,加了很多的输出流来检查)
if (count<=10&&str!="") //这个位置开始我并没有查找是否为空,就将剩余的字符push进去,导致错误
{
data.push(str); /*处理若末尾是未超过的数的输出*/
str.clear();
}
<2>传入函数的参数为指针没有加上&
<3>在处理负数的计算要先在数字的栈push进一个‘0’
<4>完成配对用“##”的配对完成
<5>无法完成小数计算,我将输入改为double类型
附上cmd运行的结果
不足之处
<1>对输入的表达式是否合法,没有进行首要的判断
<2>在处理除数为0的情况,会出现奇怪的答案
<3>没有用cmd传入的形参(后来才改正的)