结对编程 四则运算Java实现by 姚建东,李晓阳
Posted llixxiaoyyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结对编程 四则运算Java实现by 姚建东,李晓阳相关的知识,希望对你有一定的参考价值。
GitHub地址:https://github.com/YJOED/Code/tree/master/Arithmetic/src
结对人:姚建东,李晓阳。
一、项目简介:
实现一个自动生成小学四则运算题目的命令行程序
二、项目要求:
- 使用 -n 参数控制生成题目的个数(完成)
- 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。(完成)
- 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 ? e2的子表达式,那么e1 ≥ e2。(完成)
- 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。(完成)
- 每道题目中出现的运算符个数不超过3个。(完成)
- 生成的题目存入执行程序的当前目录下的Exercises.txt文件。(完成)
- 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。(完成)
- 程序应能支持一万道题目的生成。(完成)
- 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计, 统计结果输出到文件Grade.txt。(完成)
三、PSP表格:
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
60 |
60 |
· Estimate |
· 估计这个任务需要多少时间 |
60 |
60 |
Development |
开发 |
1290 |
1430 |
· Analysis |
· 需求分析 (包括学习新技术) |
240 |
360 |
· Design Spec |
· 生成设计文档 |
60 |
60 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
60 |
50 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
30 |
30 |
· Design |
· 具体设计 |
120 |
100 |
· Coding |
· 具体编码 |
600 |
720 |
· Code Review |
· 代码复审 |
60 |
60 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
120 |
150 |
Reporting |
报告 |
140 |
190 |
· Test Report |
· 测试报告 |
60 |
90 |
· Size Measurement |
· 计算工作量 |
50 |
60 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
30 |
40 |
合计 |
|
1370 |
1560 |
四、解题思路:
1、随机生成四则运算表达式,由控制台输入题目数量和生成数的范围(随机式子的长度);
2、规定生成数的为整数和真分数;
3、把整数与分数统一化,进行四则运算。
4、用后缀表达式规定其优先级,再用二叉树遍历进行计算;
5、用二叉树交换减号左右子树,使左子树大于右子树,避免出现负数;
6、将题目和答案分别写进文本中去;
7、将做题的答案与生成的答案比较,检查正确率。
五、设计实现流程:
六、代码说明:
1、主控制类:
1 import java.util.Scanner; 2 public class Arithmetic { 3 public static void main(String[] args)throws Exception { 4 Scanner input = new Scanner(System.in); 5 int range_n=0,range_r=0; 6 while (true) { 7 if(range_n!=0&&range_r!=0) { 8 new Exer_Answ().Exercises(range_n,range_r); 9 range_r=0; 10 System.out.println("Exercise.txt and Answer.txt created successful"); 11 } 12 System.out.println("please input [order] [range]:"); 13 String sip = input.nextLine(); 14 String[] s = sip.split(" "); 15 if (s.length == 2) { 16 switch (s[0]) { 17 case "-n": 18 range_n = Integer.parseInt(s[1]); 19 if (range_r == 0) System.out.println("input "-r" order"); 20 break; 21 case "-r": 22 range_r = Integer.parseInt(s[1]); 23 if (range_n == 0) System.out.println("input "-n" order"); 24 break; 25 default: 26 System.out.println("Error,input again"); 27 break; 28 } 29 }else if(s.length==4){ 30 if(sip.equals("-a Answer.txt -e Exercises.txt")||sip.equals("-e Exercises.txt -a Answer.txt")){ 31 new Grade(range_n).Count(); 32 System.out.println("Grade.txt created successful"); 33 }else System.out.println("Error,input again!"); 34 }else System.out.println("Error"); 35 } 36 } 37 }
2、计算类:
1 import java.io.PrintStream; 2 import java.util.ArrayList; 3 import java.util.Arrays; 4 5 class Exer_Answ { 6 7 Exer_Answ(){ } 8 9 void Exercises(int n,int r)throws Exception{ 10 String[] str = {"+","-","×","÷"}; 11 PrintStream f1 = new PrintStream(".\\src\\"+"Exercises.txt"); 12 PrintStream f2 = new PrintStream(".\\src\\"+"Answer.txt"); 13 for(int i=0;i<n;i++){ //生成题目数量 14 int x=(int)(1+Math.random()*3);//运算符的个数 15 String[][] s = new String[2*x+1][2] ; 16 int[][] number = new int[x+1][3]; 17 int[] parenthese=new int[2]; 18 parenthese[0]=2*x+1; 19 parenthese[1]=2*x+1; 20 boolean markl=false; 21 for(int j=0;j<2*x+1;j++) { 22 s[j][1]=j+""; 23 if (j % 2 != 0) { 24 int y = (int) (Math.random() * 4);//随机运算符 25 s[j][0] = str[y]; 26 } 27 if (j % 2 == 0) { 28 int randoms =(int)(Math.random()*5); 29 if(randoms>0){ 30 int t; 31 if(j>0&&s[j-1].equals("÷")) 32 t= (int) (Math.random() * r+1); 33 else t= (int) (Math.random() * r); 34 number[j/2][0] = t; 35 number[j/2][2] = 1; 36 s[j][0] = "" + number[j/2][0]; 37 }else if (randoms==0){ 38 int t1 = (int) (Math.random() * r+1); 39 int t2 = (int) (Math.random() * r); 40 if (t2 == 0) { 41 number[j / 2][0] = t1; 42 number[j / 2][2] = 1; 43 s[j][0] = "" + number[j / 2][0]; 44 } else if (t1 % t2 == 0) { 45 number[j / 2][0] = t1 / t2; 46 number[j / 2][2] = 1; 47 s[j][0] = "" + number[j / 2][0]; 48 } else if (t1 % t2 != 0) { 49 int[] max_t = com_div(t1, t2); 50 number[j / 2][0] = max_t[0]; 51 number[j / 2][1] = max_t[1]; 52 number[j / 2][2] = max_t[2]; 53 if (number[j / 2][0] == 0) { 54 s[j][0]= "" + number[j / 2][1] + "/" + number[j / 2][2]; 55 } else s[j][0] = "" + number[j / 2][0] + "‘" + number[j / 2][1] + "/" + number[j / 2][2]; 56 } 57 } 58 if(x>2){ 59 int rp =(int)(Math.random()*5); 60 if(j<=2*x-2&&rp==0&&!markl) { 61 parenthese[0] = j; 62 parenthese[1] = j + 2; 63 markl = true; 64 } 65 } 66 } 67 } 68 String[][] _s=new String[2*x+1][2]; 69 String[] _ss=new String[2*x+1]; 70 int[] index = new int[2*x+1]; 71 _s[0]=s[0]; 72 _ss[0]=s[0][0]; 73 index[0]=0; 74 if(parenthese[0] != 2 * x + 1 && parenthese[1] != 2 * x + 1){ 75 String[] st=s[parenthese[1]]; 76 s[parenthese[1]]=s[parenthese[1]-1]; 77 s[parenthese[1]-1]=st; 78 } 79 for(int p=0;p<x;p++) { 80 if (s[2 * p + 1][0].equals("÷") || s[2 * p + 1][0].equals("×")) { 81 if(2*p+2!=parenthese[0]) { 82 String[] stemp = s[2 * p + 1]; 83 s[2 * p + 1] = s[2 * p + 2]; 84 s[2 * p + 2] = stemp; 85 }else { 86 String[] stemp = s[2 * p + 1]; 87 s[2 * p + 1] = s[2 * p + 2]; 88 s[2 * p + 2] = s[2 * p + 3]; 89 s[2 * p + 3] = s[2 * p + 4]; 90 s[2 * p + 4] = stemp; 91 p++; 92 } 93 } 94 } 95 for(int q=1;q<2*x+1;q++){ 96 if(q<2*x) { 97 if (q + 1 != parenthese[0]) { 98 if ((s[q][0].equals("-") || s[q][0].equals("+")) && 99 (!s[q + 1][0].equals("-") && !s[q + 1][0].equals("+"))) { 100 _s[q] = s[q + 1]; 101 s[q + 1] = s[q]; 102 s[q] = _s[q]; 103 } else _s[q] = s[q]; 104 }else { 105 _s[q]=s[q+1]; 106 _s[q+1]=s[q+2]; 107 _s[q+2]=s[q+3]; 108 _s[q+3]=s[q]; 109 q=q+2; 110 } 111 } else _s[q] = s[q]; 112 } 113 for(int ii=1;ii<2*x+1;ii++){ 114 index[ii]=Integer.parseInt(_s[ii][1]); 115 _ss[ii]=_s[ii][0]; 116 } 117 ArrayList<String> slist = new ArrayList<> (Arrays.asList(_ss)); 118 BinTree t=new BinTree(); 119 t.CreateBinTree(t,slist,index,number); 120 t.Operation(t,number); 121 System.out.println(); 122 Answer(f1,f2,t,x,i,parenthese); 123 } 124 } 125 126 private void Answer(PrintStream _f1,PrintStream _f2,BinTree t,int len,int _i,int[] parenthese) { 127 String[] sarray = new String[2*len+1]; 128 int[] indexarray = new int[2*len+1]; 129 inorder(t,sarray,indexarray,2*len+1); 130 _f1.print(_i+1+"."); 131 for(int x=2*len+1;x>0;x--){ 132 if(indexarray[x-1]==parenthese[0]) _f1.print("("+" "); 133 _f1.print(sarray[x-1]+" "); 134 if(indexarray[x-1]==parenthese[1]) _f1.print(")"+" "); 135 } 136 _f1.println(); 137 _f2.print(_i+1+"."); 138 if(t.After_op[1]==0&&t.After_op[2]==1) _f2.print(""+t.After_op[0]); 139 else if(t.After_op[0]!=0)_f2.print(""+t.After_op[0]+"‘"+t.After_op[1]+"/"+t.After_op[2]); 140 else _f2.print(""+t.After_op[1]+"/"+t.After_op[2]); 141 _f2.println(); 142 } 143 144 public int[] com_div(int numerator,int denominator){//求最大公约数 145 int[] result = new int[3]; 146 int m, x=numerator,y=denominator; 147 while(y!=0){ 148 m = x%y; 149 x=y; 150 y=m; 151 } 152 numerator=numerator/x; 153 denominator=denominator/x; 154 result[0]=numerator/denominator; 155 result[1]=numerator%denominator; 156 result[2]=denominator; 157 return result; 158 } 159 160 public int[] mul(int[] _num1, int[]_num2){//乘 161 int numer = (_num1[0] * _num1[2] + _num1[1]) * (_num2[0] * _num2[2] + _num2[1]); 162 int denom = _num1[2] * _num2[2]; 163 return com_div(numer,denom); 164 } 165 166 public int[] add(int[] _num1, int[] _num2){ 167 int numer = _num2[2] * (_num1[1] + _num1[0] * _num1[2]) + _num1[2] * (_num2[1] + _num2[0] * _num2[2]); 168 int denom = _num1[2] * _num2[2]; 169 return com_div(numer,denom); 170 }//加 171 172 public int[] sub(int[] _num1, int[] _num2){ 173 int numer = _num2[2] * (_num1[1] + _num1[0] * _num1[2]) - _num1[2] * (_num2[1] + _num2[0] * _num2[2]); 174 int denom = _num1[2] * _num2[2]; 175 return com_div(numer,denom); 176 }//减 177 178 public int[] div(int[] _num1, int[] _num2){ 179 int temp; 180 temp=_num2[0]*_num2[2]+_num2[1]; 181 _num2[0]=0; 182 _num2[1]=_num2[2]; 183 _num2[2]=temp; 184 return mul(_num1,_num2); 185 }//除 186 187 public int inorder(BinTree root,String[] s,int[] in,int x){ 188 String[] _s=s; 189 int[] _in=in; 190 if(root!=null) { 191 if (root.lchild == null && root.rchild == null) { 192 _s[x - 1] = root.sdata; 193 _in[x - 1] = root.idata; 194 return x - 1; 195 } else { 196 x = inorder(root.lchild, _s, _in, x); 197 _s[x - 1] = root.sdata; 198 _in[x - 1] = root.idata; 199 x = inorder(root.rchild, _s, _in, x - 1); 200 return x; 201 } 202 }return x; 203 } //遍历生成表达式 204 }
3、生成树类:
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 4 public class BinTree { 5 public BinTree rchild; 6 public BinTree lchild; 7 public String sdata; 8 public int idata; 9 public int[] After_op; 10 11 public BinTree(){ 12 super(); 13 } 14 15 public BinTree CreateBinTree(BinTree t,ArrayList<String> slist,int[] iarray,int[][] num){ 16 if(t!=null&&slist.size()>0&&iarray.length>0) { 17 t.idata = iarray[slist.size()-1]; 18 if(t.idata%2==0) t.After_op=Arrays.copyOf(num[t.idata / 2],num[t.idata/2].length); 19 t.sdata = slist.remove(slist.size() - 1); 20 BinTree L = new BinTree(); 21 BinTree R = new BinTree(); 22 String sr=slist.get(slist.size() - 1); 23 if (sr.equals("+") || sr.equals("-") || sr.equals("×") || sr.equals("÷")) { 24 CreateBinTree(R, slist,iarray,num); 25 }else { 26 R.idata = iarray[slist.size()-1]; 27 R.sdata = slist.remove(slist.size() - 1); 28 } 29 t.rchild = R; 30 if(slist.size()>0){ 31 String sl = slist.get(slist.size() - 1); 32 if (sl.equals("+") || sl.equals("-") || sl.equals("×") || sl.equals("÷")) { 33 CreateBinTree(L, slist, iarray,num); 34 } else { 35 L.idata = iarray[slist.size() - 1]; 36 L.sdata = slist.remove(slist.size() - 1); 37 } 38 t.lchild = L; 39 } 40 } 41 return t; 42 } 43 44 public void Operation(BinTree t,int[][] num){ 45 BinTree p; 46 if(t!=null) { 47 if(t.rchild==null&&t.lchild==null) 48 t.After_op=Arrays.copyOf(num[t.idata / 2],num[t.idata/2].length); 49 if (t.lchild!= null&&t.rchild!=null) { 50 Operation(t.lchild,num); 51 Operation(t.rchild,num); 52 switch (t.sdata) { 53 case "-": 54 if (Compare(t.lchild.After_op, t.rchild.After_op)) { 55 p = t.lchild; 56 t.lchild = t.rchild; 57 t.rchild = p; 58 } 59 t.After_op = Arrays.copyOf(new Exer_Answ().sub(t.lchild.After_op, t.rchild.After_op), 3); 60 break; 61 case "+": 62 t.After_op = Arrays.copyOf(new Exer_Answ().add(t.lchild.After_op, t.rchild.After_op), 3); 63 break; 64 case "×": 65 t.After_op = Arrays.copyOf(new Exer_Answ().mul(t.lchild.After_op, t.rchild.After_op), 3); 66 break; 67 case "÷": 68 t.After_op = Arrays.copyOf(new Exer_Answ().div(t.lchild.After_op, t.rchild.After_op), 3); 69 break; 70 } 71 } 72 } 73 } 74 75 public boolean Compare(int[] num1,int[] num2){ 76 int com1=(num1[0]*num1[2]+num1[1])*num2[2]; 77 int com2=(num2[0]*num2[2]+num2[1])*num1[2]; 78 if(com1<com2) return true; 79 else return false; 80 } 81 }
4、建立文件类(以及校对):
1 import java.io.BufferedReader; 2 import java.io.FileReader; 3 import java.io.PrintStream; 4 5 public class Grade { 6 int n; 7 public Grade(int _n){ 8 n=_n; 9 } 10 void Count()throws Exception { 11 BufferedReader br_a = new BufferedReader(new FileReader(".\\src\\Answer.txt")); 12 BufferedReader br_a1 = new BufferedReader(new FileReader(".\\src\\Answer1.txt")); 13 PrintStream grade = new PrintStream(".\\src\\" + "Grade.txt"); 14 int k = 0, count_c = 0, count_w = 0; 15 int[] corrt_wrong = new int[n]; 16 String s_a, s_a1; 17 while ((s_a = br_a.readLine()) != null && (s_a1 = br_a1.readLine()) != null && k < n) { 18 if (s_a.equals(s_a1)) { 19 corrt_wrong[k] = 0; 20 count_c++; 21 } else { 22 corrt_wrong[k] = 1; 23 count_w++; 24 } 25 k++; 26 } 27 grade.print("Correct:"+" "+count_c+" ( "); 28 for(int i=0;i<n;i++){ 29 if(corrt_wrong[i]==0) grade.print(i+1+" "); 30 } 31 grade.println(")"); 32 grade.print("Wrong:"+" "+count_w+" ( "); 33 for(int i=0;i<n;i++){ 34 if(corrt_wrong[i]==1) grade.print(i+1+" "); 35 } 36 grade.println(")"); 37 38 br_a.close(); 39 br_a1.close(); 40 grade.close(); 41 } 42 }
七、测试运行:
1、控制台输入:
2、表达式:
3:、答案:
4、对错数量统计:
八、总结:
这次结对编程虽然是双人合作,但是建东同学才是核心呀,大部分的想法思路是他提供的,每次听到他的思路我是恍然大悟,自己为什么总是想不到呢,在他身上我也是学到了很多,也认识到自己身上的不足。这次的合作让我们明白了合作是多么的重要,一个人不可能方方面面都能顾及到,可以从另一个人身上学到自己没有的东西,我觉得这是这次编程最大的收获了。这一次也是为我们以后的编程打下基础,明白合作的重要性,学会去与他人合作。再次感谢我的伙伴哦。通过这一次的结对编程,让我们感觉到个人的想法有时是比较狭窄的,看不到全部问题,但通过合作,探讨,协商,我们可以不断地发现问题,细化问题,最后解决问题,结对编程弥补了我们在个人独自编程时的不足,对我们都助益良多,是一次宝贵的经验。
以上是关于结对编程 四则运算Java实现by 姚建东,李晓阳的主要内容,如果未能解决你的问题,请参考以下文章
20165219 2017-2018-2《Java程序设计》结对编程一 第一周总结