一、前言
第一次较为正式的尝试着做一个运算软件系统,虽然之前学过一段时间的JAVA,但在操作中还是遇到了重重困难,这篇博客记录了我在完成这项作业时的心路历程,希望我遇到的一些问题能够给大家提供帮助,同时也希望自己在回顾时能够有所感悟。
二、需求分析
目的是面向小学生设计一款四则运算出题软件。
(1)自动生成10道100以内的2个操作数的四则运算算式(+ - * /),要求运算结果也在100以内
(2)剔除重复算式。 2 + 3 = 和 2 + 3 = 是重复算式 2 + 3 = 和 3 + 2 = 不属于重复算式
(3)题目数量可定制
(4)相关参数可控制
是否包含乘法和除法
操作数数值范围可控(如操作数 在100以内 还是1000以内)
操作数是否含负数
(5)生成的运算题存储到外部文件result.txt中
三、设计实现
①使用java语言实现了程序的部分功能实现。
②使用函数之间的调用实现功能
③使用if语句使用逻辑判断
四、功能实现
1.编写主函数并通过,命令行接收参数
2.判断传入的参数是否合法
3.随机选择题目的数量
4.选择操作数的个数
5.选择要生成的操作数的范围
6.根据产生运算符的个数生成一定运算数的运算式并存入List集合中
7.当随机产生运算符是“/”时候判断被除数是否能整除除数,并且限制结果是否在0到100之间 如果不能随机产生能被整除的除数
8.遍历List集合通过函数计算集合中每个运算式的结果
9.生成的运算题存储到外部文件result.txt中
10选择输入是否接着生成新的题输入0退出整个系统
五、测试运行



代码部分:
1 package com;
2 import java.awt.List;
3 import java.io.File;
4 import java.io.FileWriter;
5 import java.io.IOException;
6 import java.util.ArrayList;
7 import java.util.Random;
8 import java.util.Scanner;
9
10 import javax.script.ScriptEngine;
11 import javax.script.ScriptEngineManager;
12 import javax.script.ScriptException;
13
14 public class CalculateGenerator {
15
16 private static ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");
17
18 private static final char PLUS = '+';
19 private static final char MINUS = '-';
20 private static final char MULTIPLY = '*';
21 private static final char DIVIDE = '/';
22 private static final char DISPLAY_DIVIDE = '÷';
23 private static final char EQUALS = '=';
24 private static final String DOT = ".";
25 private static final String DOT_REGEX = "\\.";
26
27 private static final char[] operators = {PLUS, MINUS, MULTIPLY, DIVIDE};
28 private static final Integer MIN_OPERATOR_COUNT = 1;
29 private static final Integer MAX_OPERATOR_COUNT = 1;
30 private static final Integer MIN_CAL_VALUE = 0;
31 private static final Integer MAX_CAL_VALUE = 100;
32
33 private static final String FILE_NAME = "result.txt";
34 private static final String STUDENT_NO = "come on";
35 private static final String NEW_LINE = "\r\n";
36
37 private static Random random = new Random();
38
39
40 public static void main(String[] args) throws ScriptException {
41 while(true){
42 System.out.println("请输入要生成的练习题数量:输入0退出");
43 Scanner scanner = new Scanner(System.in);
44 Integer expressionCount = scanner.nextInt();
45
46 if(expressionCount==0){
47 System.out.println("你已经退出系统");
48 break;
49 }
50 System.out.println("请输入操作数的范围(0-100,1000,10000)");
51 Integer bb= scanner.nextInt();
52 System.out.println("请选择操作数量;1(2个),2(3个)");
53 //Scanner scanner = new Scanner(System.in);
54 Integer aa= scanner.nextInt();
55
56
57 if(expressionCount<0&&bb<0&&bb>10000&&(aa!=1||aa!=2)){
58
59
60
61 System.out.println("你的操作有误请重新输入:");
62 }else{
63
64
65
66 ArrayList<String> expressionList = new ArrayList<>();
67 for (int i = 1; i <= expressionCount; i++) {
68 expressionList.add(getNextExpression(bb,aa));
69 System.out.println(String.format("正在生成第 %s 道题", i));
70 }
71
72 writeExpressionsToFile(expressionList);
73 System.out.println("生成练习题完成请到result.txt文件查询");
74 }
75 }
76 }
77
78
79 /**
80 * 将练习题输出到文件
81 *
82 * @param expressionList
83 */
84 private static void writeExpressionsToFile(ArrayList<String> expressionList) {
85 File file = new File(FILE_NAME);
86 try (FileWriter fileWriter = new FileWriter(file)) {
87 fileWriter.append(STUDENT_NO);
88 for (String expression : expressionList) {
89 fileWriter.append(NEW_LINE);
90 fileWriter.append(expression);
91 }
92 } catch (IOException e) {
93 e.printStackTrace();
94 }
95 }
96
97 /**
98 * 生成练习题
99 *
100 * @return
101 * @throws ScriptException
102 */
103 private static String getNextExpression(int bb,int aa) throws ScriptException {
104 System.out.println("尝试生成下一道题");
105
106
107
108
109 // 运算符数量
110 int operatorCount = random.nextInt(aa + 1 - MIN_OPERATOR_COUNT) + MIN_OPERATOR_COUNT;
111
112 StringBuilder expression = new StringBuilder();
113
114
115 // 运算符
116 ArrayList<Character> operatorList = getOperatorList(operatorCount, aa);
117
118 // 运算数
119 ArrayList<Integer> calValueList = getCalValueList(bb);
120
121 for (int i = 0; i < operatorList.size(); i++) {
122 Character operator = operatorList.get(i);
123
124 Integer previousCalValue = calValueList.get(i);
125 Integer nextCalValue = calValueList.get(i + 1);
126
127 expression.append(previousCalValue);
128
129
130
131 // 除法校验除数不为0且能被整除
132 if (DIVIDE == operator) {
133 calValueList.set(i + 1, getDivideCalValue(previousCalValue, nextCalValue));
134 } else if (MINUS == operator) {
135 // 减法校验被减数大于减数
136 // 当包含小数点时向下取整
137 String currentResultString = scriptEngine.eval(expression.toString()).toString();
138 if (currentResultString.contains(DOT)) {
139 currentResultString = currentResultString.split(DOT_REGEX)[0];
140 }
141 Integer currentResult = Integer.valueOf(currentResultString);
142 while (currentResult < nextCalValue) {
143 nextCalValue = random.nextInt(aa + 1);
144 }
145 calValueList.set(i + 1, nextCalValue);
146 }
147
148 expression.append(operator);
149 }
150
151 expression.append(calValueList.get(operatorCount));
152
153 // 计算当前结果是否为正整数
154 String result = scriptEngine.eval(expression.toString()).toString();
155
156 if (result.contains(DOT) && Integer.valueOf(result) < 0 ||Integer.valueOf(result) >100 ) {
157 System.out.println("当前题目不符合要求");
158 return getNextExpression(bb,aa);
159 }
160
161 String currentExpression = expression.append(EQUALS).append(result)
162 .toString()
163 .replaceAll(String.valueOf(DIVIDE), String.valueOf(DISPLAY_DIVIDE));
164 return currentExpression;
165 }
166
167 /**
168 * 获取运算符
169 *
170 * @param operatorCount
171 * @return
172 */
173 private static ArrayList<Character> getOperatorList(int operatorCount,int a ) {
174 ArrayList<Character> operatorList = new ArrayList<>();
175 for (int i = 0; i < operatorCount; i++) {
176
177 Character operator = operators[random.nextInt(operators.length)];
178 // operatorList.add(operator);
179 if(a==1 ){
180 if( (operator.equals(PLUS)&&operator.equals(MINUS)) ){
181 operatorList.add(operator);
182 }
183 else{
184 Character operator1 = operators[random.nextInt(operators.length)];
185 operatorList.add(operator1);
186 }
187 }else{
188 Character operator1 = operators[random.nextInt(operators.length)];
189 operatorList.add(operator1);
190 }
191 }
192 return operatorList;
193 }
194
195 /**
196 * 获取运算数
197 *
198 * @param calValueCount
199 * @return
200 */
201 private static ArrayList<Integer> getCalValueList(int calValueCount) {
202 ArrayList<Integer> calValueList = new ArrayList<>();
203
204
205
206 /*System.out.println("请输入操作数的范围(0-100,1000,1000)");
207 Scanner scanner = new Scanner(System.in);
208
209 Integer bb= scanner.nextInt();*/
210
211
212 for (int i = 0; i < calValueCount; i++) {
213
214 calValueList.add(random.nextInt(calValueCount + 1));
215
216 }
217 return calValueList;
218 }
219
220 /**
221 * 当为除法时校验除数不为0且能被整除
222 *
223 * @param previousCalValue
224 * @param nextCalValue
225 * @return
226 */
227 private static int getDivideCalValue(Integer previousCalValue, Integer nextCalValue) {
228 if (nextCalValue == 0 || previousCalValue % nextCalValue != 0) {
229 nextCalValue = random.nextInt(MAX_CAL_VALUE) + 1;
230 return getDivideCalValue(previousCalValue, nextCalValue);
231 }
232 return nextCalValue;
233 }
234 }
六、psp:
|
PSP2.1 |
任务内容 |
计划共完成需要的时间(min) |
实际完成需要的时间(min) |
|
Planning |
计划 |
55 |
80 |
|
· Estimate |
· 估计这个任务需要多少时间,并规划大致工作步骤 |
50 |
90 |
|
Development |
开发 |
300 |
360 |
|
·· Analysis |
需求分析 (包括学习新技术) |
20 |
15 |
|
· Design Spec |
· 生成设计文档 |
0 |
0 |
|
· Design Review |
· 设计复审 (和同事审核设计文档) |
0 |
0 |
|
· Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
10 |
10 |
|
· Design |
具体设计 |
20 |
35 |
|
· Coding |
具体编码 |
235 |
200 |
|
· Code Review |
· 代码复审 |
10 |
15 |
|
· Test |
· 测试(自我测试,修改代码,提交修改) |
13 |
15 |
|
Reporting |
报告 |
30 |
40 |
|
·· Test Report |
· 测试报告 |
20 |
15 |
|
· Size Measurement |
计算工作量 |
0 |
0 |
|
· Postmortem & Process Improvement Plan |
· 事后总结 ,并提出过程改进计划 |
10 |
20 |