四则运算去重 20162315-20162317 结对编程
四则运算去重 20162315-20162317 结对编程
需求分析
- 在前次作业上进行修改,使程序输出时自动将题目去重。
- 使用命令行参数输入需要的题目,并将题目输出到expression.txt这个文件夹里。
- 只涉及1到9的个位数计算,运算符只涉及+ - x /以及()。
设计思路
- 我和20162317袁逸灏同学最开始没有思路,在网上查找也找不到相似的方法。我们只能采取直接对比结果,去掉结果相同的题目的方式来完成出题。毕竟,题目不同答案不一定相同,但答案不同题目一定不同。
- 首先我们调用了上一次四则运算中的计算方法,将它写进了新的文件MathProCal中。
- 在MathPro中,我们写入了随机生成表达式和进行去重的方法。在这个类中袁逸灏同学添加了括号类的中缀转后缀表达式的方法。我们将有无括号分为两类进行计算。
- 在驱动类ExpressionGenerator中,我们调用了之前写过的两个方法,使得命令行参数第一位输入生成题目数,第二位输入生成运算符数。
实现过程中的关键代码解释
while(i <= getQuesNum()) {
String[] middle;
int choose=r.nextInt(2);
fw2 = new FileWriter("back.txt");
if(choose==1) {
middle = new String[(getSymbNum() + 1) * 2];
for (int n = 0; n < middle.length; n += 2) {
int Num = r.nextInt(9) + 1;
middle[n] = String.valueOf(Num);
}
for (int n = 1; n < middle.length; n += 2) {
String symbol = Symbol[r.nextInt(4)];
middle[n] = symbol;
if (n == middle.length - 1) {
middle[n] = "=";
}
}
这是这次的不含括号类的中缀表达式的生成方法,仍旧是偶数位(0开始)输入随机数1到9,偶数位输入运算符,将输出的结果加入等号输出成中缀表达式。
sta = new Stack<String>();
for (int n = 0; n < middle.length - 1; n++) {
//符号优先级高的
if (isOperatorFirst(middle[n])) {
sta.push(middle[n]);
}
//符号优先级低的
else if (isOperatorLatter(middle[n])) {
//若栈空则入栈
if (sta.empty()) {
sta.push(middle[n]);
}
//若栈不空栈中符号全部弹出
else {
while (!sta.empty()){
fw2.append(sta.pop() + " ");
}
sta.push(middle[n]);
}
}
//数字直接输出
else {
fw2.append(middle[n]+" ");
}
}
while (!sta.empty()){
fw2.append(sta.pop()+ " ");
}
fw2.append("\r\n");
fw2.flush();
中缀表达式转后缀表达式依然是与上次相同的方法,计算时操作数入栈,操作符出栈。
resSave[i-1]=mpc.result;
if(mpc.result.getBottom()!=1&&mpc.result.getTop()!=0) {
System.out.println(mpc.result.getTop() + "/" + mpc.result.getBottom());
}else {
System.out.println(mpc.result.getTop());
}
if(i!=1){
for(int n=0;n<i-1;n++){
if(mpc.isLike(resSave[i-1],resSave[n])){
i--;
break;
}else if(n==i-2){
for(int k=0;k<middle.length;k++){
fw.append(middle[k]+" ");
}
fw.append("\r\n");
fw.flush();
}
}
}else {
for(int k=0;k<middle.length;k++){
fw.append(middle[k]+" ");
}
fw.append("\r\n");
fw.flush();
}
}
这是最终比较的方法。reSave是表达式的运算结果,i是总共的表达式数,n是变化的,每当isLike成立一次,即出现结果相同的表达式,相同的表达式便会被去掉,这个时候i会减1,这个循环语句一直判断到n++的值达到i-2,也就是说在原有的表达式中去掉了相同表达式时,这个时候会输出中缀表达式。如果不出现相同的表达式,就进入else直接输出所有表达式了。
测试截图
对不同题目,运算符生成数的测试
运行过程截图
运行十个计算式,4个运算符的例题
代码托管地址
遇到的困难以及解决方法
问题1:如何去重?
解决方案:我们实在是想不出比较好的去重方法,只能用下册,只能比较表达式的运行结果了。调用上次的计算方法,对自动生成的表达式进行计算,去掉结果相同的式子。虽然这样做很有弊端,但至少保证绝对不会出现结果相同的表达式。
问题2:如何在将去重表现在循环语句中?
解决方案:我跟袁逸灏进行了讨论,在上面展示的代码中,我们将运算结果列为数组元素,通过对这些数组元素的比较去掉相同的表达式。
对结对的小伙伴做出评价
袁逸灏同学的自学能力非常强,在很短的时间内就自学了括号在表达式转换时的入出栈代码,并且完成了跟括号有关的计算内容。他也协助我完成了MathPro内不带括号的表达式的输入,结果的比较,去重,输出。没有袁逸灏同学的帮助,这两次四则运算的代码编写我恐怕寸步难行。如果给我们100分,我给袁逸灏同学评分65,给我自己评分35。这次大部分代码仍旧在袁逸灏的电脑上编写提交。最后有一些修改与替换是在我电脑上提交的。
git-log(bash中文显示乱码)