此作业的要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/7631
代码地位:https://e.coding.net/Eustia/f4.git
结对伙伴:杨天宇
功能1、2:支持括号四则运算
支持出题4个数的四则运算题目,所有题目要求作者有能力正确回答 。
重难点:对已生成算式内容的读取和判断;处理除法的精度问题;中缀、后缀表达式;括号的生成;后缀表达式的计算。
编程收获:以往的自己输入算式的程序很简单,于是误以为这个程序也很简单,于是在生成表达式后就傻眼了,算不出来。。于是又花了很多时间捣鼓运算符优先级这种问题,以后在编程之前一定要分析清楚功能再下手,不能盲目自信。
括号的生成也把我们难到了,不过后来想了想,只有4个数字的算式形式有限,于是就用枚举法解决了括号的问题。最后就是数据结构的知识了,只能说当初欠下的数据结构,早晚都要补回来。
重要代码片段如下:
//生成算式 void Cequation(vector<char>&infix) { infix.clear(); char r_num[5]; int temp; int e_form; push_num=0; e_form=rand()%11;//随机获得表达式格式 for(int i=0;i<13;i++) { temp=form[e_form][i]; if(temp<0)//左括号 { while(temp<0) { infix.push_back('('); temp++; push_num++; } } else if(temp>0) { if(temp==3)//数字 { itoa(rand()%9+1,r_num,10); infix.push_back(r_num[0]); push_num++; } else if(temp==4)//运算符 { infix.push_back(RdOp()); push_num++; } else//右括号 { while(temp>0) { infix.push_back(')'); push_num++; temp--; } } } } }
//数字为3,运算符为4,总共11种情况 int form[11][13]= { {0,3,4,0,3,0,4,0,3,0,4,3,0}, {-1,3,4,0,3,1,4,0,3,0,4,3,0}, {0,3,4,-1,3,0,4,0,3,1,4,3,0}, {0,3,4,0,3,0,4,-1,3,0,4,3,1}, {-1,3,4,0,3,0,4,0,3,1,4,3,0}, {0,3,4,-1,3,0,4,0,3,0,4,3,1}, {-1,3,4,0,3,1,4,-1,3,0,4,3,1}, {-2,3,4,0,3,1,4,0,3,1,4,3,0}, {0,3,4,-2,3,0,4,0,3,1,4,3,1}, {0,3,4,-1,3,0,4,-1,3,0,4,3,2}, {-1,3,4,-1,3,0,4,0,3,2,4,3,0} };
double SufCount(string &suffix) { stack<double>s; double x,y,z; for(int i=0;suffix[i]!='#';i++) { if(suffix[i]>='0'&&suffix[i]<='9') { s.push((double)suffix[i]-'0'); } else { x=s.top(); s.pop(); y=s.top(); s.pop(); z=Calculate(y,x,suffix[i]); s.push(z); } } return z; }
运行效果截图如下:
功能3:限定题目数量,"精美"打印输出,避免重复
重难点:把生成的算式输出到txt文件中去;判断重复的算式。
编程收获:避免重复这一点思考了很久都没有头绪,最后通过判断后缀表达式是否相同这一方法解决了,顺便温习了一边与文件操作有关的编程知识。
重要代码片段如下:
else if(argc==3) { int test_num; string temp=s[2]; for(int l=0;l<temp.length();l++) { if(!(temp[l]>='0'&&temp[l]<='9')) { printf("题目数量必须是 正整数。"); return 0; } } if(atoi(s[2])<=0) { printf("题目数量必须是 正整数。"); return 0; } test_num=atoi(s[2]); FILE *file=fopen("test.txt","w"); for(int i=0;i<test_num;i++) { Cequation(infix); suffix=IntoSuf(infix,push_num); ans=SufCount(suffix); for(int j=0;j<infix.size();j++) { printf("%c",infix[j]); fprintf(file,"%c",infix[j]); } printf("="); for(int k=infix.size();k<40;k++) { printf(" "); fprintf(file,"%c",32); } int_ans=(int)ans; if(ans-int_ans<0.1) { printf("%d\n",int_ans); fprintf(file,"%d\n",int_ans); } else { printf("%.1lf\n",ans); fprintf(file,"%.1lf\n",ans); } } }
运行效果截图如下:
txt文件内容截图如下:
功能4:支持分数出题和运算
此功能因水平有限,尚未实现,争取在日后完成这项功能。
总结:
1、结对编程的体会
由于以前都没有过结对编程的经历,所以在一开始时非常不适应,不知道如何交流,编程时也有放不开的感觉。但随着讨论、编程的深入,越发体会到两个人的效率就是会比一个人高,多了一份思路就少了很多卡壳的时候。结对编程也让我认识到了自己的不足,锻炼了自己与人交流、合作的能力。
2、至少5项在编码、争论、复审等活动中花费时间较长,给你较大收获的事件。
(1)在编程语言选择上,我主张用本题比较方便的python,而杨天宇同学表示python我们都不会,还是用c++比较保险,最后经过商讨决定用C++完成本次作业。
(2)在看到题目时脑袋中就模模糊糊想到了数据结构中学过这种算式处理的方法,在花时间查阅资料后深入了解了中缀、后缀表达式,以及中缀表达式如何转变为后缀表达式,收获良多。
(3)在如何生成括号这个问题上我们讨论了很多,一开始毫无头绪,后来在翻阅学长学姐们的代码时找到了灵感,最终决定使用枚举的方式解决这个问题。
(4)一开始在测试时发现除法的精度不够,在引入精度参数后依然没有解决,最后调试半天发现是运算用的栈定义成了int型,改成double型后成功解决问题。
(5)两个人在编程习惯上有不同,而且还会误解对方说的话,在适应这方面问题的时候让我收获很多,也为以后的团队合作打下了一点基础。
3、给出照片1张,包括结对的2位同学、工作地点、计算机,可选项包括其他能表达结对编程工作经历的物品或场景。
工作地点:光华公寓A411房间。
计算机:杨天宇同学的笔记本电脑。
照片: