第四次作业—结对编程 四则运算
要求1 参考《构建之法》第4章两人合作,结对编程上述功能,要求每人发布随笔1篇 (代码是共同完成的,博客是分别完成的)。
(1) 给出每个功能的重点、难点、编程收获。
功能一:支持出题4个数的四则运算题目,所有题目要求作者有能力正确回答。就是4个随机数,做加减乘除的运算,并输出结果,循环20次。算式中不可以出现括号,而且每道算式下方要输出结果,如果输出结果正确则显示”答对啦,你真是个天才!“如果答案不对,则输出”再想想吧,答案似乎是#喔!“(#是正确的答案)。结尾显示你一共答对几道题,共20道题。
重点难点1:如何生成加减乘除四则运算;
重点难点2:要对每次生成的运算结果和正确的结果进行比较,识别结果正确或者错误。
编程收获:将string类型变量转换为常用的数值类型,对其进行运算。代码如下:
void calculateQuestions(int number); //模板函数:将string类型变量转换为常用的数值类型(此方法具有普遍适用性) template <class Type> Type stringToNum(const string& str){ istringstream iss(str); Type num; iss >> num; return num; }
功能二:在功能一可以实现的情况下,对每道算式添加括号后进行运算。
重点难点:算式中括号出现的位置要正确符合算式的规则,还要处理括号内外运算的先后问题。
编程收获:我们通过手动模拟括号加入的方法,对算式进行括号的添加。代码如下:
class CalculateQuestion { int num[N]; // N个参与计算的数字 char character[M]; //M个运算符 int brackets; // 加括号方式:当只有4个数字参与运算时,有8种加括号方式 string express; // 计算表达式 public: CalculateQuestion(); string getExpressionAndResult(); ~CalculateQuestion(); friend ostream& operator<<(ostream &out, CalculateQuestion &obj); // 重写 << 运算符 }; const char character_arr[4] = { '+', '-', '*', '/' }; /* 手动模拟加括号情况 0 无 -1 ( 1 ) -2 (( 2 )) */ const int bracket_arr[9][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, { -1, 0, 0, 1, 0, 0, 0, 0 }, { 0, 0, -1, 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, -1, 0, 0, 1 }, { -1, 0, -1, 0, 0, 2, 0, 0 }, { -2, 0, 0, 1, 0, 1, 0, 0 }, { -1, 0, 0, 1, -1, 0, 0, 1 }, { 0, 0, -2, 0, 0, 1, 0, 1 }, { 0, 0, -1, 0, -1, 0, 0, 2 } };
功能三:限定题目数量,"精美"打印输出,避免重复。也就是要在控制台中输入题目数量,然后将输出结果显示在txt中.
重点难点:准确的输出题目的个数,以及如何将结果显示到txt中。
编程收获:定义outfail,outfail.open打开mytest.txt文件,outfail << res << endl;用来将算式写入文件中之后关闭文件。代码如下:
void calculateQuestions(int number) { CalculateQuestion** cq = new CalculateQuestion*[number]; srand((unsigned)time(NULL)); string res; ofstream outfail; for (int i = 0; i < number; i++) { cq[i] = new CalculateQuestion(); res = cq[i]->getExpressionAndResult(); outfail.open("mytest.txt", ios::app); if (res != "-1") { // 返回值正常为 表达式 结果 //cout << endl; cout << res << endl; //cout << res<<"############"; outfail << res << endl; } else { //如果为 -1 说明中间发现分母为 0 则再生成一道新题目 i--; //cout << "@"; } outfail.close(); } }
功能四: 支持分数出题和运算
重点难点:如何用分数进行运算。
编程收获:将分数变成假分数,假分数进行运算,再变成带分数输出。
/* 化为带分数并约分 */ string Fraction::reduct() { this->integer = this->numerator / this->denominator; // 带分数整数部分 if (this->denominator < 0) {//分数的符号 this->denominator = -this->denominator; } if (this->numerator < 0) {//分数的符号修改 this->numerator = -this->numerator; } this->numerator = this->numerator % this->denominator; // 带分数未约分的分子 // 约分:化为带分数后,分子小于分母 for (int i = 2; i <= this->numerator; i++) { // 如果分子分母都能整除 i,则 i 为公因子,分子分母同除以 i 进行约分 if (this->denominator % i == 0 && this->numerator % i == 0) { this->denominator /= i; this->numerator /= i; } } return this->toString(); }
程序运行截图:
(2)出结对编程的体会
这是我第一次以”结对编程“的方式和同学共同来完成作业,在结对编程的过程中,我们无论是在编码规范还是功能实现这些部分,都会或多或少的产生分歧,我觉得这不止是一个互怼的过程,而是一个相互学习的过程,并且在编码的过程中我们可以起到互补的作用,许多我想不到的点,队友可以给我做出解答和提醒,在这个过程中促进我们共同进步,并且让我感受到了团队协作的重要。我从队友这里学到了很多良好的编码习惯,这些都为自己的基本功打下了基础。对用C++实现四则运算有了进一步的学习,还学到了一些运算符重载的知识。
(3) 至少5项在编码、争论、复审等活动中花费时间较长,给你较大收获的事件。 (10分)
1.命名变量过程中,我并没有快速的吸收代码规范里的全部内容,导致忽略规则还是命名一些简单的单词,而且对临时起变量名这个过程很不习惯。通过这段时间的结对编程,慢慢的培养起来对变量命名的规范,让程序看起来更明了。
2.功能一的编码中,就遇到了很多问题,数字和 运算符如何读取,怎么运用栈指针。
3.功能二中,我们遇到的问题就是怎么正确的加入括号到算式中去,并且要按照运算规则来区分运算的优先级问题,最后确定手动模拟加括号的方法,将括号添加进去。
4.功能三的编码中,问题还是在如何将结果输出到txt文件中去,最后通过翻阅资料找到解决方案。
5.结对编程的过程中,两个人可以相互检查语句的错误,及时沟通解决方案,大大的提高了编程的效率,代码质量也同样得到提高。
要求2 给出照片1张,包括结对的2位同学、工作地点、计算机,可选项包括其他能表达结对编程工作经历的物品或场景。 (5分)
工作地点:传媒西楼220
计算机:Hp
编程语言:C++
要求3 使用coding.net做版本控制。checkin 前要求清理 临时文件、可执行程序,通常执行 build-clean可以达到效果。(5分)