《面向对象程序设计》c++第四次作业___calculator plus
c++第四次作业 Calculator Plus
git上的作业展示 Calculator 2.0 SourceCode in Git
PS:这次作业orz感谢某同学用windows的dev c++帮我把代码编译成可执行文件,同时感谢某学长帮我克服了sourcetree上的疑难问题。(连在命令行上的截图都是帮我编译的小伙伴帮忙的)
我的计算器的一些特点(以下特点将在下文有操作范例):
1、数字不合法(整数位大于10位)报错(
ERROR:Number Not Conform To The Requirement.
)2、除以零报错(
ERROR:Divided By Zero.
)3、9(2+3)形式的表达在括号前自动填充乘号
4、2*-3形式的表达负数可不加括号(与普通科学计算器相同)
5、左右括号数不一样多,自动在相应端补齐括号(如:-(3-(-(2+3)+4 等同于-(3-(-(2+3)+4)) )
6、引入次方计算(如:2^3 等于 2的3次方)
我的计算器的一些不足:
1、没有使用大多数同学的前缀表达式、后缀表达式
2、没能实现四则运算与乘方以外的运算
这里有些特别想说的是,我的代码最希望与别人分享的内容并不是那些实现了计算器功能的部分,而是那些注释掉的过程输出,那些语句一方面体现了程序编码过程中艰辛的调试过程,而且一个编码人对自己的代码进行检测、修改过程中的输出更能体现编程的思想、对自己代码的掌控,所以保留了那部分点代码,仅仅注释掉。也希望更多同行可以和我分享更好的调试方法。
代码:
Scan.hpp
#ifndef Scan_hpp
#define Scan_hpp
#include <iostream>
#include <queue>
#include <string>
#include <cmath>
using namespace std;
class Scan {
private:
string input;
string charString;
public:
bool tooBig;
queue<string> ToStringQueue(string input,int mol);
};
#endif
Scan.cpp
这个文件生成两个队列,分别用于输出表达式和送入 Calculation 类中计算,分别对应参数1和2
#include "Scan.hpp"
#include <iostream>
#include <queue>
#include <string>
#include <cmath>
using namespace std;
queue<string> Scan::ToStringQueue(string input,int mol) {
tooBig=false;
input[input.length()]='+';
int count=0,flag=0,bracket=0;
string item = "";
std::queue<string> outCharQueue,calculationCharQueue;
for (int i=0; i<input.length(); i++) {
if (input[i]=='(') {
bracket++;
}else if (input[i]==')') {
bracket--;
}
}
if (bracket<0) {
for (int i=0; i>bracket; i--) {
calculationCharQueue.push("(");
}
}
for (int i=0; i<input.length(); i++) {
if ((i==0 && input[i]=='-')||(input[i-1]=='(' && input[i]=='-')) {
outCharQueue.push("-");
calculationCharQueue.push("0");
calculationCharQueue.push("-");
calculationCharQueue.push("1");
calculationCharQueue.push("*");
}
else if ((input[i]=='-')&&(input[i-1]=='+' ||input[i-1]=='-' ||
input[i-1]=='*' ||input[i-1]=='/' || input[i-1]=='^')) {
outCharQueue.push("-");
calculationCharQueue.push("(");
calculationCharQueue.push("0");
calculationCharQueue.push("-");
calculationCharQueue.push("1");
calculationCharQueue.push("*");
flag=1;
}
else if (input[i]=='+' || input[i]=='-'|| input[i]=='*' ||
input[i]=='/' || input[i]=='^'||input[i]=='(' || input[i]==')' ) {
if(!item.empty()){
outCharQueue.push(item);
calculationCharQueue.push(item);
}
item.clear();
count = 0;
if (flag==1) {
calculationCharQueue.push(")");
flag=0;
}
if (input[i]=='(' && input[i-1]>='0' && input[i-1]>='9') {
calculationCharQueue.push("*");
}
item = input[i];
outCharQueue.push(item);
calculationCharQueue.push(item);
item.clear();
}
else if ((input[i] >= 48 && input[i] <=57) || input[i] == '.' ) {
item += input[i];
if (input[i] != '.') {
count++;
}
if (count >= 10) {
tooBig = true;
}
}
}
if (!item.empty()) {
outCharQueue.push(item);
calculationCharQueue.push(item);
if (flag==1) {
calculationCharQueue.push(")");
flag=0;
}
}
if (bracket>0) {
for (int i=0; i<bracket; i++) {
calculationCharQueue.push(")");
}
}
calculationCharQueue.push("|");
if (mol==2) return calculationCharQueue;
return outCharQueue;
}
Calculation.hpp
#ifndef Calculation_hpp
#define Calculation_hpp
#include <iostream>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
class Calculation {
private:
queue<string> q;
stack<double> num;
stack<string> op;
public:
int idbz;
int oplevel(string op);
int check(string cur);
double toDouble(string num);
double calculating(queue<string> q);
double solve(double num1,double num2,string op);
};
#endif
Calculation.cpp
这个文件中有很多保留的过程输出语句
solve()函数里的第一行语句可以查看进入函数的两个运算数与一个运算符、倒数第三行语句可以查看计算过后的结果,作用在于查看每次的计算是不是你所想预想的。
calculating()函数里的类似 cout << q.front() << " &push A num" << endl 这样的语句输出每次进入运算数栈、操作符栈的变量是不是你所预想的。
- 1、solve()函数debug语句的使用
- 2、calculating()函数debug语句的使用
#include "Calculation.hpp"
#include <iostream>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
int Calculation::oplevel(string op) {
idbz=0;
int level;
if (op[0]=='+' || op[0]=='-') {
level=2;
}else if (op[0]=='*' || op[0]=='/') {
level=3;
}else if (op[0]=='^') {
level=4;
}else if (op[0]==')' || op[0]=='(') {
level=1;
}else if (op[0]=='|') {
level=0;
}
return level;
}
double Calculation::toDouble(string num) {
stringstream s;
double number=0;
s << num;
s >> number;
return number;
}
double Calculation::solve(double num1, double num2, string op) {
// cout << num1 << " " << num2 << " " << op << " ";
if (op[0]=='+') {
num1=num1+num2;
}
if (op[0]=='-') {
num1=num1-num2;
}
if (op[0]=='*') {
num1=num1*num2;
}
if (op[0]=='/') {
if (num2!=0) {
num1=num1/num2;
}
else {
idbz=1;
return 0;
}
}
if (op[0]=='^') {
num1=pow(num1, num2);
}
// cout << num1 << endl;
return num1;
}
double Calculation::calculating(queue<string> q) {
double result=0,num1,num2;
string cur,curop;
while (!q.empty()) {
cur=q.front();
if (cur[0]=='(') {
op.push(cur);
q.pop();
if (q.front()[0]!='(') {//123
num.push(toDouble(q.front()));//123
// cout << q.front() << " &push A num" << endl;
q.pop();
}//123
}
else {
if (num.empty()) {
num.push(toDouble(cur));
// cout << cur << " &push B num" << endl;
q.pop();
cur=q.front();
}
while (!op.empty()) {
if (oplevel(cur)>oplevel(op.top()) || op.top()[0]=='(') break;
num2=num.top();num.pop();
num1=num.top();num.pop();
curop=op.top();op.pop();
// cout << num1 << " " << num2 << " " << curop << endl;
num1=solve(num1, num2, curop);
if (num1==0 && idbz==1) {
return 0;
}
num.push(num1);
// cout << num1 << " &push D num" << endl;
}
if (cur[0]==')' && op.top()[0]=='(') {
op.pop();
q.pop();
}else if (cur[0]=='|') {
break;
}else {
op.push(cur);
// cout << cur << " &push E op" << endl;
q.pop();
if (q.front()[0]!='(') {
num.push(toDouble(q.front()));
// cout << q.front() << " &push C num" << endl;
q.pop();
}
}
}
}
result=num.top();num.pop();
return result;
}
Print.hpp
#ifndef Print_hpp
#define Print_hpp
#include <iostream>
#include <queue>
#include <string>
#include <cmath>
using namespace std;
class Print {
public:
void printString(queue<string> charQueue,int mol);
};
#endif
Print.cpp
#include "Print.hpp"
#include <iostream>
#include <queue>
#include <string>
#include <cmath>
void Print::printString(queue<string> charQueue,int mol) {
if (mol==1) {
while (!charQueue.empty()) {
cout << charQueue.front() << endl;
charQueue.pop();
}
cout << endl;
}
else if (mol==2){
while (!charQueue.empty()) {
cout << charQueue.front();
charQueue.pop();
}
cout << " = " ;
}
}
main.cpp
#include <iostream>
#include <queue>
#include <string>
#include <cmath>
#include "Print.hpp"
#include "Calculation.hpp"
#include "Scan.hpp"
using namespace std;
int main(int argc,char *argv[]) {
string input;
Scan m_scan;
Print m_pr;
Calculation m_cal;
// getline(cin,input);
if (argc>1) {
if (argc==2) {
input=*(argv+1);
m_scan.ToStringQueue(input, 2);
if (m_scan.tooBig==true) {
cout << "ERROR:Number Not Conform To The Requirement." << endl;
}
else {
m_cal.calculating(m_scan.ToStringQueue(input,2));
if (m_cal.idbz==1) {
cout << "ERROR:Divided By Zero." << endl;
}else if (m_cal.idbz==0){
cout << m_cal.calculating(m_scan.ToStringQueue(input,2)) << endl;
}
}
}else if (argc==3) {
input=*(argv+1);
if (input=="-a") {
input=*(argv+2);
m_pr.printString(m_scan.ToStringQueue(input,1),2);
}
input=*(argv+2);
m_scan.ToStringQueue(input, 2);
if (m_scan.tooBig==true) {
cout << "ERROR:Number Not Conform To The Requirement." << endl;
}
else {
m_pr.printString(m_scan.ToStringQueue(input,1),2);
m_cal.calculating(m_scan.ToStringQueue(input,2));
if (m_cal.idbz==1) {
cout << "ERROR:Divided By Zero." << endl;
}else if (m_cal.idbz==0){
cout << m_cal.calculating(m_scan.ToStringQueue(input,2)) << endl;
}
}
}
}
return 0;
}
- 1、数字不合法(整数位大于10位)报错
- 2、除以零报错
- 3、9(2+3)形式的表达在括号前自动填充乘号
- 4、2*-3形式的表达负数可不加括号(与普通科学计算器相同)
- 5、左右括号数不一样多,自动在相应端补齐括号
对比
- 6、纯计算结果
- 7、-a计算结果
《面向对象程序设计》c++第四次作业___calculator plus的更多相关文章
- 《Java程序设计》十四次作业
<Java程序设计>十四次作业实验总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 3. 代码量统计 周次 总代码量 新增代码量 总文件数 新增 ...
- 2016-2017-2 20155339《 java面向对象程序设计》实验四Android程序设计
2016-2017-2 20155339< java面向对象程序设计>实验四Android程序设计 实验内容 1.Android Stuidio的安装测试: 参考<Java和Andr ...
- sdut 面向对象程序设计上机练习四(变量引用)
面向对象程序设计上机练习四(变量引用) Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 将变量的引用作为函数形參,实现2个int型数据交换. 输入 输入2 ...
- C语言程序设计实验第四次作业
(一)改错题 输出三角形的面积和周长,输入三角形的三条边a.b.c,如果能构成一个三角形,输出面积area和周长perimeter(保留2位小数):否则,输出"These sides do ...
- 《面向对象程序设计》第三次作业 Calculator
c++第三次作业 Calculator git上的作业展示点这里. ps:有一点不是很明确,作业要求:将数字和符号提取出来,得到一组string,然后才将这些string存入队列中.按我的理解是需要将 ...
- 面向对象课程 - 寒假第四次作业 - C++计算器项目计算部分
C++计算器项目计算部分 零.项目源文件地址 地址:Calculator 2.0 一.项目信息相关 项 目 : Calculator 版 本 : 2 . 0 日 期 : 2016 . 4 . 14 实 ...
- 面向对象程序设计(C++)_作业一_设计、定义并实现Complex类
源代码: 运行结果:
- THE LAST ONE!! 2017《面向对象程序设计》课程作业八
THE LAST ONE!! 2017<面向对象程序设计>课程作业八 031602230 卢恺翔 GitHub传送门 题目描述 1.时间匆匆,本学期的博客作业就要结束了,是否有点不舍,是否 ...
- 面向对象程序设计第四单元总结(UML系列)
2019面向对象程序设计第四单元总结 前言 本单元是面向对象程序设计课程的最后一个单元了,本单元是和UML模型相关,也就是说,我们需要正确理解UML模型的基础上,对构建出的UML模型进行解析,但是 ...
随机推荐
- 我理解的js中预解释
浏览器在执行代码前,先找带var和带function的地方,把带var的声明且赋予初始值undefined,把带function的声明且定义. 带var关键字预解释 让我们先看下这段代码执行的结果: ...
- histoty显示时间戳
设置Linux可以查看历史命令的执行时间 大家都知道Linux平台上,可以通过history命令查看最近所执行过的命令,但history命令默认所显示的只有编号和命令的,只知道命令是最近所执行 ...
- 微信 weui 初体验
最近微信推出他们自己的H5组件(weui)组件的优点有两个: 做为开发者的我们可以不用写太多css,直接拿过来就可以用. 组件都有点击态,大大增加了用户的体验好感 高清屏幕下 border : 0.5 ...
- IDEA中Maven切换国内源
国内访问Maven仓库非常慢,笔者今天忘记切换国内源更新Maven仓库竟然更新了一下午.如果改成国内的源,那么很快就更新完成了. 在IDEA中打开“Settings”(快捷键++): 在搜索框中输入“ ...
- WebForm控件多字段绑定
一.这里的多字段绑定是什么意思? 多字段绑定控件其实就是把两个字段显示在一起作为一个字段现在控件上! 可能读者看了可能还是有点懵逼,说的还是比较抽象!的确,光从这上面的确是无法具体到某特定一种情况!那 ...
- MVC 导出Execl 的总结几种方式 (四)
这种方式我个人还是比较喜欢的,使用部分视图的方式,导出Execl 这样在编辑样式上也是很方便的 第一步: 编辑导出视图页 @using H5UpdateImage.Models; @{ Layout ...
- Java8简明学习之Lambda表达式
函数式接口 就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,函数式接口可以被隐式转换为lambda表达式. 之前已有的函数式接口: java.lang.Runnable java.uti ...
- Windows下Sqlplus中显示乱码
set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK 如果想显示英文 Set nls_lang=american_america.zhs16gbk 注意,前提是 ...
- 使用CSS3改变文本选中的默认颜色——张鑫旭
关于浏览器文字选中颜色 以我的系统举例(xp 默认主题),浏览器上页面文字选中后默认的背景色是一种蓝色, 不同浏览器的颜色有些许差异,但大致相同,文字颜色也近乎白色,如下图所示,截自Firefox3. ...
- 【代码笔记】iOS-gif图片播放
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...