第三次作业——计算器
2016-02-22 13:11
211 查看
作业链接
queue模板类的定义在头文件中。queue模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型。定义queue对象的示例代码如下:
1.push——入队:eg. que.push(x): 将x接到队列que的末端。
2.pop——出队:eg.que.pop():弹出队列的第一个元素即最先被插入的元素,注意,并不会返回被弹出元素的值。
3.size——访问队列中的元素个数。
4.empty——判断队列是否空,如果队列为空,返回true。
5.front——访问队首元素,即最早被压入队列的元素。
6.back——访问队尾元素,即最后被压入队列的元素。
1.头文件
2.实现文件
3.客户文件
![](https://images2015.cnblogs.com/blog/885804/201602/885804-20160223161755958-1683594162.png)
error中的信息提示我可能是通过非成员函数访问操作了私有部分的数据,但是回看代码的过程颇为迷茫,因为我将Print类与read函数都设为Scan的友元,所以在试了多次改>正的办法都没有解决,半天下来也有些心浮气躁,可能因为书此时看得还是颇少,掌握东西的量还不足,对于一些错误无法查找出来。在Google中也并未找到解决的方法。在自学有时还是颇感迷茫的,因为时常出了问题在搜索的基础上不足以解决,又无旁人的指点。这个问题也暂且放下,同时也在此作为一个保存,等再一步深入学习C++再回头来解决。
2.实现文件:
3.客户文件
![](https://images2015.cnblogs.com/blog/885804/201602/885804-20160223210637677-899462384.png)
经过第一次的失败(包含多次试验失败)又暂时没有有效的解决方法后,放弃了原有的思路。在ToStringQueue函数编写中不再使用void类型,因为没有返回值的同时一定要对private里面的队列数据进行访问,而此时编写的函数一直访问失败,所以直接让ToStringQueue函数返回一个队列,这样在使用Print类过程中就无需访问Scan类中的私有数据了。
OPP编程思想的实现需要去努力理解并且融会贯通,虽然在之前学习有接触到这个思想,在之前博客关于链表实现的实例也有提到,但仍需加强理解。数据隐藏作为OPP编程思想的一大特点,虽然第一次尝试代码中有想着将数据隐藏起来,但是在实现中不尽人意,也没有解决的方案。
这个作业前后花了不少时间,一开始的计划是学习关于类等语法知识,然后完成作业。但是在学习的过程中,一开始并没有动手自己实践一些代码,看书学习的这个过程总是萌生困意,对于类的知识也是迷迷糊糊,一知半解,浪费了不少时间。最后改变了计划,一边动手实践代码一边看书,但是这样也有着很大的弊端,因为在程序出问题的时候,没有对于类的总体把关,很难看出其中错误,搜索的过程也显得较为费力。总之,“试了很多错”,在这些错误中也了解到一些知识。希望在以后的学习过程中,在多多少少的“试错”过程中,能尽快找到合适自己的学习方法。现在回看这整个程序,好像都是简简单单的代码,实现也颇显简单,但是完成这份程序又确确实实用了不少时间。所以,这同时给了自己一个很大的警钟——路阻且长,仍需更加努力。
GitHub链接:传送门
预备知识:
在自学的过程还未了解到关于queue的知识,所以预先Google了一下相关知识。queue
queue模板类的定义在头文件中。queue模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型。定义queue对象的示例代码如下:
queue<int> q1; queue<double> q2
queue基本操作
1.push——入队:eg. que.push(x): 将x接到队列que的末端。
queue<string> que; que.push("Hello World!"); que.push("OK");
2.pop——出队:eg.que.pop():弹出队列的第一个元素即最先被插入的元素,注意,并不会返回被弹出元素的值。
que<string>que; que.push("Hello World!"); que.push("OK"); que.pop(); //此时"Hello World"被删除
3.size——访问队列中的元素个数。
queue<string> que; cout<<que.size()<<endl; que.push("Hello World!"); que.push("OK"); cout << que.size() << endl; //输出分别为“0”和“2”
4.empty——判断队列是否空,如果队列为空,返回true。
queue<string> que; cout << que.empty() << endl; que.push("Hello World!"); que.push("OK"); cout << que.empty() << endl; //输出分别为“1”和“0”
5.front——访问队首元素,即最早被压入队列的元素。
queue<string> que; q.push("Hello World!"); q.push("OK"); cout << que.front() << endl; que.pop(); cout << que.front() << endl; //输出为"Hello World"和"OK"
6.back——访问队尾元素,即最后被压入队列的元素。
queue<string> que; que.push("Hello World!"); que.push("OK");
cout << que.back() << endl; //输出为"OK"
思路:
按照题目要求,将输入交给Scan类,输出交给Print类1.头文件
#ifndef CALCULATOR_H_ #define CALCULATOR_H_ #include<string> #include<queue> using namespace std; class Scan { friend istream &read(istream &, Scan &); friend class Print; private: string ipt; queue<string>que; public: void ToStringQueue(string input); }; class Print { public: void output(queue<string>q); }; istream &read(istream &, Scan &); #endif
2.实现文件
#include<iostream> #include<string> #include<queue> #include "calculator.h" using namespace std; /*********************************** Description: 读取并扫描表达式,将数字与符号分开压入队列 Others: 当输入数学表达式中有数字(含小数位)超过10位即报错并终止程序 ***********************************/ void Scan::ToStringQueue(string input) { int len = input.size(); for (int i;i<len;) { string tmp = ""; while (i < len && input[i] <= '9' && input[i] >= '0') { tmp += input[i++]; } if(tmp.size() > 10) { cerr << "ERROR!"; while (!que.empty()) { que.pop(); } break; } if (!tmp.empty()) { que.push(tmp); } while (i < len && (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/' || input[i] == '(' ||input[i] == ')')) { tmp = input[i++]; que.push(tmp); } } } /*********************************** Description : 输出队列中的数据 ***********************************/ void Print::output(queue<string>q) { while (!q.empty()) { cout << q.front() << endl; q.pop(); } } /*********************************** Description:从给定流中 将数据读到给定的对象中 Others: 本意是将此函数包含至Scan类中,让读入的功能都让专门的类实现, 但是在实际操作过程中,确颇感困难,所以就独自定义了一个类相关的非成员函数 ***********************************/ istream &read(istream &is, Scan &expr) { is >> expr.ipt; return is; }
3.客户文件
#include<iostream> #include<string> #include"calculator.h" int main() { Scan in; Print opt; read(cin,in); in.ToStringQueue(in.ipt); opt.output(in.que); return 0; }
运行结果:
![](https://images2015.cnblogs.com/blog/885804/201602/885804-20160223161755958-1683594162.png)
程序分析:
error中的信息提示我可能是通过非成员函数访问操作了私有部分的数据,但是回看代码的过程颇为迷茫,因为我将Print类与read函数都设为Scan的友元,所以在试了多次改>正的办法都没有解决,半天下来也有些心浮气躁,可能因为书此时看得还是颇少,掌握东西的量还不足,对于一些错误无法查找出来。在Google中也并未找到解决的方法。在自学有时还是颇感迷茫的,因为时常出了问题在搜索的基础上不足以解决,又无旁人的指点。这个问题也暂且放下,同时也在此作为一个保存,等再一步深入学习C++再回头来解决。
第二次尝试:
1.头文件:#ifndef CALCULATOR_H_ #define CALCULATOR_H_ #include<string> #include<queue> using namespace std; class Scan { private: //string in; friend istream &read(istream &, Scan &); public: string in; queue<string>ToStringQueue(string input); }; class Print { public: void output(queue<string>q); }; istream &read(istream &, Scan &); #endif
2.实现文件:
#include<iostream> #include<string> #include<queue> #include "calculator.h" using namespace std; /*********************************** Description: 读取并扫描表达式,将数字与符号分开压入队列 Others: 当输入数学表达式中有数字(含小数位)超过10位即报错并终止程序 ***********************************/ queue<string>Scan::ToStringQueue(string input) { int len = input.size(); queue<string>que; for (int i=0;i<len;) { string tmp = ""; while (i < len && input[i] <= '9' && input[i] >= '0') { tmp += input[i++]; } if(tmp.size() > 10) { cerr << "ERROR!"; while (!que.empty()) { que.pop(); } break; } if (!tmp.empty()) { que.push(tmp); } while (i < len && (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/' || input[i] == '(' ||input[i] == ')')) { tmp = input[i++]; que.push(tmp); } } return que; } void Print::output(queue<string>q) { while (!q.empty()) { cout << q.front() << endl; q.pop(); } } /*********************************** Description:从给定流中 将数据读到给定的对象中 Others: 本意是将此函数包含至Scan类中,让读入的功能都让专门的类实现, 但是在实际操作过程中,确颇感困难,所以就独自定义了一个类相关的非成员函数 ***********************************/ istream &read(istream &is, Scan &expr) { is >> expr.in; return is; }
3.客户文件
#include<iostream> #include<string> #include<queue> #include"calculator.h" int main() { Scan ipt; Print opt; queue<string>que; read(cin,ipt); que = ipt.ToStringQueue(ipt.in); opt.output(que); return 0; }
运行结果:
![](https://images2015.cnblogs.com/blog/885804/201602/885804-20160223210637677-899462384.png)
程序分析:
经过第一次的失败(包含多次试验失败)又暂时没有有效的解决方法后,放弃了原有的思路。在ToStringQueue函数编写中不再使用void类型,因为没有返回值的同时一定要对private里面的队列数据进行访问,而此时编写的函数一直访问失败,所以直接让ToStringQueue函数返回一个队列,这样在使用Print类过程中就无需访问Scan类中的私有数据了。
反思:
OPP编程思想的实现需要去努力理解并且融会贯通,虽然在之前学习有接触到这个思想,在之前博客关于链表实现的实例也有提到,但仍需加强理解。数据隐藏作为OPP编程思想的一大特点,虽然第一次尝试代码中有想着将数据隐藏起来,但是在实现中不尽人意,也没有解决的方案。
总结:
这个作业前后花了不少时间,一开始的计划是学习关于类等语法知识,然后完成作业。但是在学习的过程中,一开始并没有动手自己实践一些代码,看书学习的这个过程总是萌生困意,对于类的知识也是迷迷糊糊,一知半解,浪费了不少时间。最后改变了计划,一边动手实践代码一边看书,但是这样也有着很大的弊端,因为在程序出问题的时候,没有对于类的总体把关,很难看出其中错误,搜索的过程也显得较为费力。总之,“试了很多错”,在这些错误中也了解到一些知识。希望在以后的学习过程中,在多多少少的“试错”过程中,能尽快找到合适自己的学习方法。现在回看这整个程序,好像都是简简单单的代码,实现也颇显简单,但是完成这份程序又确确实实用了不少时间。所以,这同时给了自己一个很大的警钟——路阻且长,仍需更加努力。
相关文章推荐
- 哈理工oj hrbust 1996 数学等式【哈希表】
- 重载确定
- C#软件设计——小话设计模式原则之:依赖倒置原则DIP
- 【04】AngularJS 表达式
- 证书签发者无效问题
- 根据权重随机读取数据
- iOS小明开发笔记(三) (cocoaPod的简单使用)
- java 计算程序运行的时间
- 接口的好处
- can't able to update the design capacity in bq27441-G1
- 修改的不使用库的Qt示例程序——Spectrum Analyzer
- EditText属性及使用
- golang语法总结(四):基本数据类型
- linux usb系统
- 【免费下载】《这样理解知识管理》电子书,2016学会知识管理
- iOS-图片上传(第三方服务器)实现图片的上传和获取
- HTML5 Video
- STM-库开发4
- iOS所有常用证书,appID,Provisioning Profiles配置说明及制作图文教程
- phpexcel使用说明4