[Github上的代码提交(Calculator文件)](https://github.com/Olivia1011/object-oriented/tree/master/Calculator)
1.解题思路
Scan类
题目要求在这个类中写一个函数,用来处理输入的字符串(input)。我的初步思路是将数字和符号分开再按顺序储存到队列中。怎样才能做到按顺序储存到对列呢?首先,我设计一个for循环,并在其中添加判断初步实现将数字与字符分开。其次,我们要考虑如何将数字整个储存如对列,于是我在判断字符后添加一个判断,来实现如该字符前有数字,将数字储存入对列并清除数字储存变量num和数字位数计量变量count。再次,在for循环外添加一个if判断,若输入字符串input的最后是数字,将这些数字也储存入对列,到这里将数字和符号分开再按顺序储存到队列中已经基本完成。最后,我们还要对程序添加报错的功能,也就是判断为数字时给数字计算位数,若超过十位(包括小数点位),则直接报错。在这里我们要记得一个细节,就是我们需要将队列清空,防止在之后执行Print时将队列中的信息输出。
Print类
相对于Scan类,Print类的书写就相对简单一些。我写了一个for循环(循环次数为)来按顺序输出对列,每次都输出对列的第一个,输出后再删除第一个,于是到下一次执行时对列中的第二个就变成了第一个,这样就实现了按顺序输出。
2.发现错误与调试
(1)发现输入字符串后只能输出前一半。原因是在Print类中for循环使用了que_input.size()
,而随着循环的进行,que_input.size()
的值在不断缩小。于是我另外定义了一个变量使其等于que_input.size()
并用于for
循环中,如下:
void print(queue<string>que_input) //输出queue
{
int count2=que_input.size(); //设置一个变量等于队列长度
for(int k=0; k<count2; k++)
{
cout<<que_input.front()<<endl;
que_input.pop();
}
}
(2)发现当输入的input
中含有超过10位的数字时,输出结果除了报错外还输出了该数字之前的数字与字符。原因是程序缺少一个当出现错误时将对列清空以防止输出的语句。于是进行了如下修改:
if(temp==1) //若出错清空queue防止输出
{
int count1=que_input.size();
for(int j=0; j<count1; j++)
{
que_input.pop();
}
}
return que_input;
}
(3)我的代码原本是写在一个cpp
中,所以在后来的分文件过程中也出现了问题。因为缺少头文件,导致程序编译无法通过
(4)由于我在Scan.h
文件中声明函数时将ToStringQueue()
函数用void声明,导致函数的返回值为空,导致主函数que_character=INPUT.ToStringQueue (character);
语句在编译时无法通过。后修改为用queue
声明
3.完整代码呈现
Scan.h
#ifndef SCAN_H
#define SCAN_H
#include<string>
#include<iostream>
#include<queue>
using namespace std;
class Scan
{
public:
queue<string> ToStringQueue(string input);
};
endif
Scan.cpp
#include "Scan.h"
#include<string>
#include<iostream>
#include<queue>
using namespace std;
queue<string> Scan::ToStringQueue (string input)
{
queue<string>que_input;
string num=""; //储存数字
string sym=""; //储存符号
int count=0; //记录数字位数
int i;
int temp=0; //记录输入是否出错
for(i=0; i<input.size(); i++)
{
if(input[i] >= '0' && input[i] <= '9' || input[i]=='.') //判断是数字或小数点
{
num+=input[i]; //记录下数字
count++; //记录下数字位数
if(count>10) //若超出十位报错并跳出循环 ,同时记录下错误
{
cout << "More than ten...Error!" << endl;
num="";
break;
temp=1;
}
}
else if(input[i]=='+' || input[i]=='-' || input[i]=='*' || input[i]=='/' || input[i]=='(' || input[i]==')') //判断是符号
{
if(num!="") //判断该符号之前是否为数字
{
que_input.push(num); //若之前为数字,将数字输出
num=""; //清空数字储存变量
count=0; //清空记录数字位数变量
}
sym=input[i];
que_input.push(sym); //将字符push到queue上
}
}
if(num!="") //判断字符串最后一位是不是数字
{
que_input.push(num);
num="";
count=0;
}
if(temp==1) //若出错清空queue防止输出
{
int count1=que_input.size();
for(int j=0; j<count1; j++)
{
que_input.pop();
}
}
return que_input;
}
Print.h
#ifndef PRINT_H
#define PRINT_H
#include<string>
#include<iostream>
#include<queue>
using namespace std;
class Print
{
public:
void print(queue<string>que_input);
};
#endif
Print.cpp
#include "Print.h"
#include<string>
#include<iostream>
#include<queue>
using namespace std;
void Print::print(queue<string>que_input) //输出queue
{
int count2=que_input.size(); //设置一个变量等于队列长度
for(int k=0; k<count2; k++)
{
cout<<que_input.front()<<endl;
que_input.pop();
}
}
>Calculator.cpp
#include "Scan.h"
#include "Print.h"
#include<iostream>
#include<queue>
#include<string>
#include<iostream>
using namespace std;
int main()
{
string character;
queue<string>que_character;
Scan INPUT;
Print OUTPUT;
cin>>character;
que_character=INPUT.ToStringQueue (character);
OUTPUT.print(que_character);
return 0;
}
4.自我思考
在做这次作业之前我学习了慕课课程中的起航篇,离岗篇还有继承篇,同时看了C++ primer这本书上有关于类部分的一些语句使用。str 和 queue则是通过上网搜索他们的语句和用法来学习的。虽然在开始编写代码之前做了这些准备工作但是在实际操作中还是遇到了很多的难题,后来通过于同学的讨论才慢慢的有了思路。在编写程序是我常常会犯一些很低级的错误,琢磨半天也没有发现问题出在哪,在之后的学习中我希望能够尽量避免这些错误。
在完成作业之后,我翻看了其他同学的代码,发现我的程序还有很多不够优化的地方,比如在判断是符号时,不需要一长串或的叠加,还有输出的循环用while也会简便许多。