一、魔法传送门:

问题描述:点我点我点我!

仓库地址:点我点我点我!

二、网上资料:

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.测试结果:





2.一些方法:

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

四、总结与感受:

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

关于Calculator的第四次作业的更多相关文章

  1. 《面向对象程序设计》c++第四次作业___calculator plus

    c++第四次作业 Calculator Plus git上的作业展示 Calculator 2.0 SourceCode in Git PS:这次作业orz感谢某同学用windows的dev c++帮 ...

  2. c++的路上,我坚信,我可以 -----第四次作业体会

    第四次作业 传送门 1.浅谈"新对象"sstream和stack 第四次作业,就是在第三次作业上作修改,上周周末,我刚刚才完成了第三次作业,但是知道了队列如何应用,面对这次的sta ...

  3. 耿丹CS16-2班第四次作业汇总

    Deadline: 2016-10-13 12:00 作业内容 实验3-1 分别使用while循环.do while循环.for循环求1+2+3+ --+100. 实验3-2 分别使用while循环. ...

  4. 第四次作业——WORDSEARCH小游戏

    “谁想出来的这么缺德的题目啊!!!!”一个声音在我心中回荡 这个题目很早就在课堂上公布了,我和我的小伙伴都惊呆了! 这是个毛?根本无从下手的感觉 总是觉得这个小游戏不是程序能给出答案的,因为我的第一印 ...

  5. 网络1711班 C语言第四次作业批改总结

    网络1711班 C语言第四次作业批改总结 助教有话说(写在前面) 近来,有同学跟老师和助教们反映:博客作业太多太麻烦,而且对编程能力提高似乎没什么帮助?在这里我要谈一谈我的感想. 博客作业的意义? 首 ...

  6. 第四次作业之oop

    第四次作业 四则运算 类 输入类:用户输入题数和答案,语言选择. 生成类:随机数字,运算符,生成表达式. 读取类:读取表达式,计算正确答案. 界面类:选择语言,输出正确题数和答案. 类与类之间是如何进 ...

  7. C#基础第四天-作业答案-Hashtable-list<KeyValuePair>泛型实现名片

    .Hashtable 实现 Hashtable table = new Hashtable(); while (true) { Console.WriteLine("------------ ...

  8. C#基础第四天-作业-Hashtable-list<KeyValuePair>泛型实现名片

    1.名片集: 名片集实现功能:不限定集合实现 增加,查询,查询全部,删除 功能,需求条件: 根据姓名去(查询/删除)某一行数据.指定:姓名,年龄,性别,爱好,联系方式. 采用技术:Hashtable- ...

  9. 《Java程序设计》十四次作业

    <Java程序设计>十四次作业实验总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 3. 代码量统计 周次 总代码量 新增代码量 总文件数 新增 ...

随机推荐

  1. 深入了解Java虚拟机(3-1)虚拟机类加载机制

    虚拟机类加载机制 一.类加载的阶段和时机 1.阶段 整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化(I ...

  2. Linux 文件IO管理 - POSIX

    以下是对POSIX的简短解释: POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),POSIX标准定义了操 ...

  3. C#绑定数据

    1.<asp:DropDownList <asp:DropDownList ID="ddlclientType" runat="server" Wi ...

  4. Storm框架:Storm整合springboot

    我们知道Storm本身是一个独立运行的分布式流式数据处理框架,Springboot也是一个独立运行的web框架.那么如何在Strom框架中集成Springboot使得我们能够在Storm开发中运用Sp ...

  5. apicloud api.openwin

    简单介绍api.openWin: 打开window 若window已存在,则会把该window显示到最前面,同时若url有变化或者reload参数为true时,页面会重新加载.若当前正在进行openW ...

  6. Django HTML 转义

    HTML转义 模板对上下文传递的字符串进行输出时,会对以下字符自动转义 小于号< 转换为< 大于号> 转换为> 单引号' 转换为' 双引号" 转换为 " 与 ...

  7. try,except用法

    lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"] # 模拟for循环 it = lst.__iter_ ...

  8. Linux常用指令大全

    2017-03-25   16:35:42 刚开始学习Linux,由于记忆力有限,把平时常用的Linux命令整理出来,以便随时查阅:  linux 基本命令    ls     (list 显示当前目 ...

  9. java图形用户界面之列表框

    列表框通过Swing组件JList产生,其总是在屏幕上占据固定行数的空间.如果要得到列表框中被选中的元素,只需调用getSelectedValuesList(),它可以产生一个字符串数组,内容为被选中 ...

  10. gulpjs的使用介绍及技巧

    gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速 ...