博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《面向对象程序设计》c++第四次作业___calculator plus
阅读量:5319 次
发布时间:2019-06-14

本文共 7612 字,大约阅读时间需要 25 分钟。

c++第四次作业 Calculator Plus


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 
#include
#include
#include
using namespace std;class Scan {private: string input; string charString;public: bool tooBig; queue
ToStringQueue(string input,int mol);};#endif

Scan.cpp

这个文件生成两个队列,分别用于输出表达式和送入 Calculation 类中计算,分别对应参数1和2

#include "Scan.hpp"#include 
#include
#include
#include
using namespace std;queue
Scan::ToStringQueue(string input,int mol) { tooBig=false; input[input.length()]='+'; int count=0,flag=0,bracket=0; string item = ""; std::queue
outCharQueue,calculationCharQueue; for (int i=0; i
bracket; i--) { calculationCharQueue.push("("); } } for (int i=0; i
='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

Calculation.hpp

#ifndef Calculation_hpp#define Calculation_hpp#include 
#include
#include
#include
#include
using namespace std;class Calculation {private: queue
q; stack
num; stack
op;public: int idbz; int oplevel(string op); int check(string cur); double toDouble(string num); double calculating(queue
q); double solve(double num1,double num2,string op);};#endif

Calculation.cpp

这个文件中有很多保留的过程输出语句

solve()函数里的第一行语句可以查看进入函数的两个运算数与一个运算符、倒数第三行语句可以查看计算过后的结果,作用在于查看每次的计算是不是你所想预想的。

calculating()函数里的类似 cout << q.front() << " &push A num" << endl 这样的语句输出每次进入运算数栈、操作符栈的变量是不是你所预想的。


  • 1、solve()函数debug语句的使用

886162-20160414232646738-569609175.png


  • 2、calculating()函数debug语句的使用

886162-20160414232705004-967529782.png


#include "Calculation.hpp"#include 
#include
#include
#include
#include
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
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 
#include
#include
#include
using namespace std;class Print {public: void printString(queue
charQueue,int mol);};#endif

Print.cpp

#include "Print.hpp"#include 
#include
#include
#include
void Print::printString(queue
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 
#include
#include
#include
#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位)报错

886162-20160414232726238-1188489355.png


  • 2、除以零报错

886162-20160414232739879-1385926845.png


  • 3、9(2+3)形式的表达在括号前自动填充乘号

886162-20160414232755770-595333671.png


  • 4、2*-3形式的表达负数可不加括号(与普通科学计算器相同)

886162-20160414232830754-2084590484.png


  • 5、左右括号数不一样多,自动在相应端补齐括号

886162-20160414232848098-265446544.png

对比

886162-20160414232901473-1469863884.png


  • 6、纯计算结果

886162-20160414232919941-835168251.png


  • 7、-a计算结果

886162-20160414232931363-1668226510.png

转载于:https://www.cnblogs.com/vayhang-E-airshiner/p/5393610.html

你可能感兴趣的文章
全面分析Java的垃圾回收机制2
查看>>
[Code Festival 2017 qual A] C: Palindromic Matrix
查看>>
修改博客园css样式
查看>>
Python3 高阶函数
查看>>
初始面向对象
查看>>
leetcode Letter Combinations of a Phone Number
查看>>
Unity 5.4 测试版本新特性---因吹丝停
查看>>
7.5 文件操作
查看>>
MyEclipse中将普通Java项目convert(转化)为Maven项目
查看>>
node js 安装.node-gyp/8.9.4 权限 无法访问
查看>>
windows基本命令
查看>>
VMware中CentOS设置静态IP
查看>>
[poj1006]Biorhythms
查看>>
Hyper-V虚拟机上安装一个图形界面的Linux系统
查看>>
Hover功能
查看>>
js千分位处理
查看>>
Mac---------三指拖移
查看>>
字符串类型的相互转换
查看>>
HTTP状态码
查看>>
iOS如何过滤掉文本中特殊字符
查看>>