结对项目----实现一个自动生成小学四则运算题目的命令行程序

Posted Johann丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结对项目----实现一个自动生成小学四则运算题目的命令行程序相关的知识,希望对你有一定的参考价值。

一.Github项目地址:https://github.com/lyh27/exercise

  团队成员:卢耀恒3118005065    莫政3118005067

 

二.需求

自然数:0, 1, 2, …。

  • 真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
  • 运算符:+, −, ×, ÷。
  • 括号:(, )。
  • 等号:=。
  • 分隔符:空格(用于四则运算符和等号前后)。
  • 算术表达式:

e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),

其中e, e1和e2为表达式,n为自然数或真分数。

  • 四则运算题目:e = ,其中e为算术表达式。

 

  1. 使用 -n 参数控制生成题目的个数,例如

 

Myapp.exe -n 10

 

将生成10个题目。

  1. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如

 

Myapp.exe -r 10

 

将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。

  1. 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2。
  2. 生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数。
  3. 每道题目中出现的运算符个数不超过3个。
  4. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。

生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:

 

  1. 四则运算题目1
  2. 四则运算题目2

……

 

其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。

  1. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:

 

  1. 答案1
  2. 答案2

 

特别的,真分数的运算如下例所示:1/6 + 1/8 = 7/24。

  1. 程序应能支持一万道题目的生成。
  2. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:

 

Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt

 

统计结果输出到文件Grade.txt,格式如下:

 

Correct: 5 (1, 3, 5, 7, 9)

Wrong: 5 (2, 4, 6, 8, 10)

 

三.PSP表格

PSP2.1

Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 60
· Estimate · 估计这个任务需要多少时间 0 0
Development 开发 1500 1550
Analysis 需求分析 (包括学习新技术) 120 100
Design Spec 生成设计文档 60 55
Design Review 设计复审 (和同事审核设计文档) 20 20
Coding Standard 代码规范 (为目前的开发制定合适的规范) 0 0
Design 具体设计 60 55
Coding 具体编码 1300 1350
Code Review 代码复审 100 80
Test 测试(自我测试,修改代码,提交修改) 120 140
Reporting 报告 30 25
Test Report 测试报告 20 20
Size Measurement 计算工作量 0 0
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 60 50
合计   1870 2050

四.效能分析

 

 

生成1万道题时总的内存与CPU情况

 

 

 具体各个类的情况,其中字符串占比最多

四.设计实现过程

Util类(主要的工具类)实现分数题目的形成,整数题目的形成,分数类题目的运算操作,将题目插入文本文件,以及答案的检查。

util类主要分成了AnswerCheckUtil(答案的检查,正确与错误),ExerciseFractionUtil(生成分数题目),ExerciseIntegerUtil(生成整数题目),ExerciseInsertUtil(将题目与答案输出,写入文本文件),FractionOperationUtil(分数的操作),其中

ExerciseFractionUtil中通过设置随机符号与随机符号数,分类实现,又Math.random函数实现随机,由用户输入题目个数以及题目中数值范围实现对随机题目的控制,当输入进后,由代码实现随机生成。

ExerciseIntegerUtil同分数类的情况

FractionOperationUtil中有方法simplifiedFraction,changeToProperFraction,simplified。simplified递归实现求最大公约数,simplifiedFraction对simplified的调用,实现对分数的化简,而changeToProperFraction则是将假分数变成真分数,化成x\'x/x的形式

ExerciseInsertUtil则是对生成的题目与答案输入到文本文件中

AnswerCheckUtil则是将用户输入的答案与标准答案进行对比,批改,若正确则记录,错误也记录,最终输入正确与错误的题号。

由于对于查重未知如何实现,所以最后没有做到查重的功能,而且对于整数部分的除法也未转换成分数的形式

 

 五.代码说明

 

 

 主方法,main函数

 1 package exercise.main;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 import java.util.Scanner;
 6 
 7 import exercise.utils.AnswerCheckUtil;
 8 import exercise.utils.ExerciseFractionUtil;
 9 import exercise.utils.ExerciseIntegerUtil;
10 
11 public class main {
12 
13     @SuppressWarnings("resource")
14     public static void main(String[] args) {
15         //n表示输入题目数量,x表示输入数字的范围
16         int choose,n,x,over;
17         System.out.println("自动生成小学四则运算题目");
18         while(true) {
19             Scanner scanner=new Scanner(System.in);
20             System.out.println("请选择你需要出的题目的类型,1是整数类型,2是分数类型");
21             //判断是否输入为数字
22             if(!scanner.hasNextInt())
23                 continue;
24             choose=scanner.nextInt();
25             if(choose==1) {
26                 System.out.println("请输入出题的数量以及数字的范围");
27                 n=new Scanner(System.in).nextInt();
28                 x=new Scanner(System.in).nextInt();
29                 ExerciseIntegerUtil.getExerise(n, x);
30                 File file=new File("1.txt");
31                     try {
32                         if(!file.exists())
33                             file.createNewFile();
34                     } catch (IOException e) {
35                         // TODO Auto-generated catch block
36                         e.printStackTrace();
37                     }
38                 System.out.println("请在1.txt中作答,答题完毕请输入1");
39                 over=scanner.nextInt();
40                 //判断是否输入正确
41                 while(over!=1) {
42                     System.out.println("输入有误,请重新输入");
43                     over=new Scanner(System.in).nextInt();
44                 }
45                 AnswerCheckUtil.checkAnswer();
46             }
47             else if(choose==2) {
48                 System.out.println("请输入出题的数量以及数字的范围");
49                 n=new Scanner(System.in).nextInt();
50                 x=new Scanner(System.in).nextInt();
51                 ExerciseFractionUtil.getExercise(n, x);
52                 File file=new File("1.txt");
53                 try {
54                     if(!file.exists())
55                         file.createNewFile();
56                 } catch (IOException e) {
57                     // TODO Auto-generated catch block
58                     e.printStackTrace();
59                 }
60                 System.out.println("请在1.txt中作答,答题完毕请输入1");
61                 over=scanner.nextInt();
62                 while(over!=1) {
63                     System.out.println("输入有误,请重新输入");
64                     over=new Scanner(System.in).nextInt();
65                 }
66                 AnswerCheckUtil.checkAnswer();
67             }
68             else {
69                 System.out.println("你输入有误");
70             }
71         }
72     }
73 
74 }

ExerciseFractionUtil类

  1 package exercise.utils;
  2 
  3 /**
  4  * @author lyh 
  5  * 全部为分数的题目
  6  */
  7 public class ExerciseFractionUtil {
  8 
  9     // n为传入的题目数量,x为传入的数值范围
 10     public static void getExercise(int n, int x) {
 11         // 结果
 12         int sum = 0;
 13         // 题目数量
 14         int count = 0;
 15         // 数值,运算符,运算符个数
 16         int a, b, c, d, e, f, g, h, operator1, operator2, operator3, nterms;
 17         // 储存题目以及答案
 18         String[] results = new String[n + 1];
 19         String[] exercise = new String[n + 1];
 20         // 随机运算符+-*/,0表示+,1表示-,2表示*,3表示/
 21         while (n != count) {
 22             operator1 = (int) (Math.random() * 4);
 23             operator2 = (int) (Math.random() * 4);
 24             operator3 = (int) (Math.random() * 4);
 25             a = (int) (Math.random() * x);
 26             b = (int) (Math.random() * x);
 27             c = (int) (Math.random() * x);
 28             d = (int) (Math.random() * x);
 29             e = (int) (Math.random() * x);
 30             f = (int) (Math.random() * x);
 31             g = (int) (Math.random() * x);
 32             h = (int) (Math.random() * x);
 33             nterms = (int) (Math.random() * 3);
 34             //一个运算符的情况下
 35             if (b != 0 && d != 0 && nterms == 0) {
 36                 if (operator1 == 0) {
 37                     exercise[++count] = a + "/" + b + "+" + c + "/" + d + "=";
 38                     // 储存临时值,方便化简
 39                     sum = a * d + b * c;
 40                     b = b * d;
 41                     //判断是否为假分数,下同
 42                     if (sum > b)
 43                         //将其转换成带分数,下同
 44                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
 45                     else
 46                         //将分数化简,下同
 47                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
 48                 } else if (operator1 == 1) {
 49                     if ((a / b) > (c / d)) {
 50                         exercise[++count] = a + "/" + b + "-" + c + "/" + d + "=";
 51                         // 储存临时值,方便化简
 52                         sum = a * d - b * c;
 53                         b = b * d;
 54                         if (sum > b)
 55                             results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
 56                         else
 57                             results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
 58                     }
 59                 } else if (operator1 == 2) {
 60                     exercise[++count] = a + "/" + b + "×" + c + "/" + d + "=";
 61                     // 储存临时值,方便化简
 62                     sum = a * c;
 63                     b = b * d;
 64                     if (sum > b)
 65                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
 66                     else
 67                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
 68                 } else if (operator1 == 3) {
 69                     // 防止C为0出错
 70                     if (c == 0)
 71                         continue;
 72                     exercise[++count] = a + "/" + b + "÷" + c + "/" + d + "=";
 73                     // 储存临时值,方便化简
 74                     sum = a * d;
 75                     b = b * c;
 76                     if (sum > b)
 77                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
 78                     else
 79                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
 80                 }
 81                 //两个运算符的情况下
 82             } else if (b != 0 && d != 0 && f != 0 && nterms == 1) {
 83                 if (operator1 == 0) {
 84                     if (operator2 == 0) {
 85                         exercise[++count] = a + "/" + b + "+" + c + "/" + d + "+" + e + "/" + f + "=";
 86                         b = b * d * f;
 87                         sum = a * d * f + c * b * f + e * b * d;
 88                         if (sum > b)
 89                             results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
 90                         else
 91                             results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
 92                     }
 93                 } else if (operator2 == 1) {
 94                     if ((a / b + c / d - e / f) > 0) {
 95                         exercise[++count] = a + "/" + b + "+" + c + "/" + d + "-" + e + "/" + f + "=";
 96                         b = b * d * f;
 97                         sum = a * d * f + c * b * f - e * b * d;
 98                         if (sum > b)
 99                             results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
100                         else
101                             results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
102                     }
103                 } else if (operator2 == 2) {
104                     exercise[++count] = a + "/" + b + "+" + c + "/" + d + "×" + e + "/" + f + "=";
105                     sum = a * d * f + c * e * b;
106                     b = b * d * f;
107                     if (sum > b)
108                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
109                     else
110                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
111                 } else if (operator2 == 3 && e != 0) {
112                     exercise[++count] = a + "/" + b + "+" + c + "/" + d + "÷" + e + "/" + f + "=";
113                     sum = a * d * e + c * f * b;
114                     b = b * d * e;
115                     if (sum > b)
116                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
117                     else
118                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
119                 } else if (operator1 == 1) {
120                     if (operator2 == 0)
121                         if ((a / b - c / d + e / f) > 0) {
122                             exercise[++count] = a + "/" + b + "-" + c + "/" + d + "+" + e + "/" + f + "=";
123                             sum = a * d * f - c * b * f + e * b * d;
124                             b = b * d * f;
125                             if (sum > b)
126                                 results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
127                             else
128                                 results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
129                         } else if (operator2 == 1)
130                             if ((a / b - c / d - e / f) > 0) {
131                                 exercise[++count] = a + "/" + b + "-" + c + "/" + d + "-" + e + "/" + f + "=";
132                                 sum = a * d * f - c * b * f - e * b * d;
133                                 b = b * d * f;
134                                 if (sum > b)
135                                     results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
136                                 else
137                                     results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
138                             } else if (operator2 == 2) {
139                                 if ((a / b - (c / d) * (e / f)) > 0) {
140                                     exercise[++count] = a + "/" + b + "-" + c + "/" + d + "×" + e + "/" + f + "=";
141                                     sum = a * d * f - b * c * e;
142                                     b = b * d * f;
143                                     if (sum > b)
144                                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
145                                     else
146                                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
147                                 }
148                             } else if (operator2 == 3) {
149                                 if ((a / b - (c / d) / (e / f)) > 0) {
150                                     exercise[++count] = a + "/" + b + "-" + c + "/" + d + "÷" + e + "/" + f + "=";
151                                     sum = a * d * e - b * c * f;
152                                     b = b * d * e;
153                                     if (sum > b)
154                                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
155                                     else
156                                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
157                                 }
158                             } else if (operator1 == 2) {
159                                 exercise[++count] = a + "/" + b + "×" + c + "/" + d + "×" + e + "/" + f + "=";
160                                 sum = a * c * e;
161                                 b = b * d * f;
162                                 if (sum > b)
163                                     results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
164                                 else
165                                     results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
166                             } else if (operator1 == 3) {
167                                 if (a / b * c / d * e / f >= 0) {
168                                     exercise[++count] = a + "/" + b + "÷" + c + "/" + d + "÷" + e + "/" + f + "=";
169                                     sum = a * d * f;
170                                     b = b * c * e;
171                                     if (sum > b)
172                                         results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
173                                     else
174                                         results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
175                                 }
176                             }
177                     //3个运算符的情况下,仅仅举出了较为简单的运算+法
178                 } else if (b != 0 && d != 0 && f != 0 && h != 0 && nterms == 2) {
179                     if (operator1 == 0 && operator2 == 0 && operator3 == 0) {
180                         exercise[++count] = a + "/" + b + "+" + c + "/" + d + "+" + e + "/" + f + "+" + g + "/" + h
181                                 + "=";
182                         sum = a * d * f * h + c * b * f * h + e * b * d * h + g * b * d * f;
183                         b = b * d * f * h;
184                         if (sum > b)
185                             results[count] = FractionOperationUtil.changeToProperFraction(sum, b);
186                         else
187                             results[count] = FractionOperationUtil.simplifiedFraction(sum, b);
188                     }
189                 }
190             }
191         }
192         // 此处为实现将答案存入文本文件
193         ExerciseInsertUtil.insertExercise(exercise);
194         ExerciseInsertUtil.insertAnswer(results);
195         // 将答案存起来
196         AnswerCheckUtil.setResults(results);
197     }
198 }

ExerciseIntegerUtil类

  1 package exercise.utils;
  2 
  3 /**
  4  * @author lyh
  5  *    全部为整数的题目
  6  */
  7 public class ExerciseIntegerUtil {
  8     
  9     /*
 10      * 未处理除法的情况下变为分数 
 11      * 仅仅是变成了两位小数输出
 12      */
 13 
 14     //n为传入的题目数量,x为传入的数值范围
 15     public static void getExerise(int n,int x) {    
 16         //结果
 17         double sum=0;
 18         //题目数量
 19         int count=0;
 20         double[] results=new double[n+1];
 21         String[] exercise=new String[n+1];
 22         while(count!=n) {
 23             //四个数据a,b,c,d
 24             double a=(int) (Math.random()*x)+1;
 25             double b=(int) (Math.random()*x)+1;
 26             double c=(int) (Math.random()*x)+1;
 27             double d=(int) (Math.random()*x)+1;
 28             //随机运算符+-*/,0表示+,1表示-,2表示*,3表示/
 29             int operator1=(int) (Math.random()*4);    
 30             int operator2=(int) (Math.random()*4);
 31             int operator3=(int) (Math.random()*4);
 32             //控制题目的项数,0表示2两项,1表示3项,2表示4项
 33             int nterms=(int) (Math.random()*3);
 34             //运算符为1个的情况下
 35             if(operator1==0&&nterms==0) {
 36                 sum=a+b;
 37                 exercise[++count]=a+"+"+b+"=";
 38             }
 39             //运算符为2个的情况下
 40             else if(operator1==0&&operator2==0&&nterms==1) {
 41                 sum=a+b+c;
 42                 exercise[++count]=a+"+"+b+"+"+c+"=";
 43             }
 44             else if(operator1==0&&operator2==2&&nterms==1) {
 45                 sum=a+b*c;
 46                 exercise[++count]=a+"+"+b+"×"+c+"=";
 47             }
 48             else if(operator1==0&&operator2==1&&nterms==1) {
 49                 if(a+b<c) {
 50                     sum=a+c-b;
 51                     exercise[++count]=a+"+"+c+"-"+b+"=";
 52                 }
 53                 else {
 54                     sum=a+b-c;
 55                     exercise[++count]=a+"+"+b+"-"+c+"=";
 56                 }
 57             }
 58             20165227 结对编程项目-四则运算 第一周

结对项目

结对项目:四则运算题目生成器(JAVA+GUI)

20165330 结对编程项目-四则运算 第二周

结对编程Java实现四则运算(林伯浩 刘育明)

20175325 第二周结对编程项目 四则运算