标签:ase 需求分析 提交 运算表达式 文件 数值 stand evel 左右子树
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//生成题目数量
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) {
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(jmarkl) {
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) {
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){
96 if(qx) {
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){
114 index[ii]=Integer.parseInt(_s[ii][1]);
115 _ss[ii]=_s[ii][0];
116 }
117 ArrayList 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 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(com1return 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){
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){
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 姚建东,李晓阳
标签:ase 需求分析 提交 运算表达式 文件 数值 stand evel 左右子树
原文地址:https://www.cnblogs.com/LliXxiaoYyang/p/9728916.html