结对项目(JAVA)
结队项目:自动生成小学四则运算题目(JAVA)
一、Github项目地址(合作人:黄煜淇、郭沛)
https://github.com/huange7/arithmetic
二、题目叙述
2.1题目数字以及运算符要求:
- 真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
- 自然数:0, 1, 2, …。
- 运算符:+, −, ×, ÷。
- 括号:(, )。
- 等号:=。
- 分隔符:空格(用于四则运算符和等号前后)。
- 算术表达式:
e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),
其中e, e1和e2为表达式,n为自然数或真分数。
- 四则运算题目:e = ,其中e为算术表达式。
2.2 生成题目具体操作过程及格式:
- 使用 -n 参数控制生成题目的个数,例如: Myapp.exe -n 10 将生成10个题目。
- 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如 :Myapp.exe -r 10 将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。
- 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2。
- 生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数。
- 每道题目中出现的运算符个数不超过3个。
- 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,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
- 四则运算题目2
……
其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。
- 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:
答案1
答案2
- 真分数的运算如下例所示:1/6 + 1/8 = 7/24。
- 程序应能支持一万道题目的生成。
- 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:
Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt 统计结果输出到文件Grade.txt,格式如下:
Correct: 5 (1, 3, 5, 7, 9)
Wrong: 5 (2, 4, 6, 8, 10)
其中“:”后面的数字5表示对/错的题目的数量,括号内的是对/错题目的编号。为简单起见,假设输入的题目都是按照顺序编号的符合规范的题目。
三、解题思路
1、首先是生成题目的实现思路:(伪代码如下)
步骤:
if 随机方法
{
随机生成操作符数量 operatorsNumber
计算括号上限数量 limit
随机生成数字 List<String> numberList
随机生成运算符 List<Character>
}
for
if 满足括号条件 && 未达到括号数量上限
if 随机方法
左括号添加
数字添加
if 满足括号条件 && 括号数量大于0
if 随机方法
右括号添加
运算符添加
endfor
将未闭合的括号进行闭合
2、其次,得到一个表达式后,便开始对其进行计算,实现思路如下:
- 将表达式中的所有真分数转换成假分数;
- 将中缀表达式转化成后缀表达式,转换过程利用了栈的先进后出的特点;
- 之后便是后缀表达式的计算过程:从左到右遍历中缀表达式中的每一个数字和符号;若是数字则进栈;若为符号,则把栈顶的两个数字出栈,进行运算(两个数运算过程见下方叙述),运算结果再进栈,直到获得最终结果;
-
两个数运算过程:首先判断两个数是否为分数形式,若为分数形式则调用分数计算的方法,整数则对应整数的运算方法;在处理除号运算时,若分母为0,则会返回ERROR字符串;
- 最后的计算结果若为负数或者计算的结果超出用户要求的限定范围,则也会返回ERROR字符串;
四、设计实现过程
主要分成几个大类:Main、Service、ShowGraphic、Calculate以及AnswerFile,具体流程图如下:

五、关键代码说明
Main函数:
public class Main {
public static void main(String[] args) {
Service service = new ServiceImpl();
service.main(args);
}
}
ServiceImpl类:实现参数校验、调用GUI界面功能以及计算等核心功能
public class ServiceImpl implements Service {
private List<String> answerList = new ArrayList<>();
public static List<LinkedList<String>> numberList = new ArrayList<>();
public static List<LinkedList<Character>> charList = new ArrayList<>();
@Override
public void generateQuestion(Integer number) {
// 清空答案列表
answerList.clear();
Operations operations = new Operations();
int times = 0;
while (number > 0) {
AnswerResult answerResult = new AnswerResult();
String operation = operations.generateOperations();
String resultString = Calculate.getResult(operation, ArgsUtil.numberBound);
if ("ERROR".equals(resultString)) {
numberList.remove(numberList.size() - 1);
charList.remove(charList.size() - 1);
continue;
}
if (checkExpression(resultString)){
numberList.remove(numberList.size() - 1);
charList.remove(charList.size() - 1);
times++;
if (times == 16){
System.out.println("生成题目时冲突多次!");
break;
}
continue;
}
answerResult.setQuestion(operation + " =");
answerList.add(resultString);
Controller.operationData.add(answerResult);
number--;
}
if (!ArgsUtil.isX) {
// 将题目展示在控制台
System.out.println("-----------------------------------------");
printQuestion();
}
// 将答案写到文件
try {
AnswerFile.writeFile(answerList, true);
} catch (IOException e) {
System.out.println("生成答案文件异常");
}
System.out.println("答案文件已经存放在:" + AnswerFile.address);
if (!ArgsUtil.isX) {
downloadQuestion();
}
}
private boolean checkExpression(String result){
if (answerList.size() <= 0){
return false;
}
int now = answerList.size();
boolean flag = false;
// 获取当前表达式
List<String> nowNumber = numberList.get(now);
List<Character> nowChar = charList.get(now);
for (int i = 0; i < answerList.size() - 1; i++){
if (!result.equals(answerList.get(i))){
continue;
}
List<String> iNumber = numberList.get(i);
List<Character> iChar = charList.get(i);
// 如果数字的大小和字符的大小相等,则进行进一步的验证
if (!(iNumber.size() == nowNumber.size() && iChar.size() == nowChar.size())){
continue;
}
boolean bs = false;
// 查看是否存在
for (String iString : iNumber){
if (!nowNumber.contains(iString)){
bs = true;
break;
}
}
if (bs){
continue;
}
for (Character iC : iChar){
if (!nowChar.contains(iC)){
bs = true;
break;
}
}
if (bs){
continue;
}
flag = true;
}
return flag;
}
private void printQuestion() {
Controller.operationData.forEach(answerResult -> {
System.out.println(answerResult.questionProperty().getValue());
System.out.println("-----------------------------------------");
});
}
@Override
public int[] checkQuestion() {
File exerciseFile = new File(ArgsUtil.questionPath);
File answerFile = new File(ArgsUtil.answerPath);
Map<Integer, String> result = AnswerFile.checkAnswer(exerciseFile, answerFile);
if (result == null){
System.out.println("文件不存在!");
return null;
}
int right = 0, error = 0;
String Right = "";
String Error = "";
for (int i = 1; i <= result.size(); i++) {
if (result.get(i).equals("right")) {
right++;
if (Right.equals("")) {
Right = Right + i;
}
else {
Right = Right + ", " + i;
}
}
else {
error++;
if (Error.equals("")) {
Error = Error + i;
}
else {
Error = Error + ", " + i;
}
}
}
System.out.println("Correct: " + right + "(" + Right + ")" +"\r\n" + "Wrong: " + error + "(" + Error + ")");
return new int[]{right, error};
}
@Override
public void downloadQuestion() {
// 生成题目文件
try {
AnswerFile.writeFile(Controller.operationData, false);
} catch (IOException e) {
System.out.println("生成题目文件时失败");
}
System.out.println("题目文件已经存放在:" + AnswerFile.address);
}
@Override
public void main(String[] args) {
// 进行参数的校验
if (!ArgsUtil.verifyArgs(args, false)) {
System.out.println("参数输入错误!");
return;
}
// 展开图形界面
if (ArgsUtil.isX) {
ShowGraphic.show(args);
return;
}
// 进行处理
if (ArgsUtil.isGenerate) {
// 生成题目
generateQuestion(ArgsUtil.questionNumber);
}else {
// 进行答案的校对
checkQuestion();
}
}
}
Operation实现算术表达式的生成
public class Operations {
// 记录运算符数量
private Integer operatorsNumber;
// 记录括号的位置
private List<Integer> bracketsPos = new ArrayList<>();
// 括号最大值
private static final Integer MAX_BRACKETS = 2;
// 括号已结束
private static final Integer USED = -1;
// 记录已经使用的运算符数量
private int count = 0;
// 括号的限制数量
private int limit = 0;
// 存储数字
private LinkedList<String> numberList;
// 存储符号
private LinkedList<Character> characters;
public String generateOperations() {
StringBuffer stringBuilder = new StringBuffer();
if (randomSelective()) {
init(true);
}else {
init(false);
}
Iterator<String> iteratorNumber = numberList.iterator();
Iterator<Character> iteratorChar = characters.iterator();
for (int i = 0; ; i++) {
if (i % 2 == 0) {
generateLeftBracket(stringBuilder);
stringBuilder.append(iteratorNumber.next());
} else {
generateRightBracket(stringBuilder, false);
stringBuilder.append(iteratorChar.next());
count++;
}
if (!iteratorNumber.hasNext()) {
break;
}
stringBuilder.append(" ");
}
generateRightBracket(stringBuilder, true);
destroy();
return stringBuilder.toString();
}
private void init(Boolean isTrueFraction) {
// 随机生成操作符数量
operatorsNumber = new Random().nextInt(3) + 1;
// 设置括号的上限数量
limit = operatorsNumber == 3 ? 2 : operatorsNumber == 1 ? 0 : 1;
// 随机生成数字
generateNumber(isTrueFraction);
// 随机生成操作符
generateChar();
ServiceImpl.numberList.add(numberList);
ServiceImpl.charList.add(characters);
}
private void destroy() {
// 对数字进行归零
operatorsNumber = 0;
// 对括号位置进行置零
bracketsPos.clear();
// 对操作符数量进行置零
count = 0;
// 对括号上限进行置零
limit = 0;
}
// 随机生成数字(整数或真分数)
private void generateNumber(Boolean isTrueFraction) {
numberList = new LinkedList<>();
for (int i = 0; i < operatorsNumber + 1; i++) {
numberList.add(buildNumber(isTrueFraction));
}
}
private String buildNumber(Boolean isTrueFraction) {
if (isTrueFraction && randomSelective()) {
// 保证生成大于0
int left;
do {
left = new Random().nextInt(ArgsUtil.numberBound);
}while (left <= 0);
// 控制分母在10以内
int mother;
do{
mother = new Random().nextInt(ArgsUtil.numberBound < 11 ? ArgsUtil.numberBound : 11);
}while (mother <= 0);
int son;
// 保证生成最简分数
do {
son = new Random().nextInt(mother) + 1;
}while (!isSimplest(son, mother));
return left + "'" + son + "/" + mother;
} else {
return String.valueOf(new Random().nextInt(ArgsUtil.numberBound));
}
}
// 求出最简分数
private boolean isSimplest(int son, int mother){
int tempMo = mother, tempSon = son;
int r = tempMo % tempSon;
while ( r > 0){
tempMo = tempSon;
tempSon = r;
r = tempMo % tempSon;
}
return tempSon == 1;
}
// 随机生成运算符
private void generateChar() {
characters = new LinkedList<>();
String chars = "+-×÷";
for (int i = 0; i < operatorsNumber; i++) {
characters.add(chars.charAt(new Random().nextInt(chars.length())));
}
}
// 随机选择算法
private boolean randomSelective() {
return new Random().nextInt(2) == 1;
}
// 生成左括号
private void generateLeftBracket(StringBuffer stringBuilder) {
for (int i = 0; i < limit; i++) {
if (bracketsPos.size() >= limit) {
break;
}
if (count >= operatorsNumber) {
break;
}
if (count == 0 || (stringBuilder.charAt(stringBuilder.length() - 1) < '0' ||
stringBuilder.charAt(stringBuilder.length() - 1) > '9')) {
if (!bracketsPos.isEmpty() && count - bracketsPos.get(0) > 1) {
break;
}
if (!bracketsPos.isEmpty() && count == bracketsPos.get(0) && bracketsPos.get(0) == operatorsNumber - 1) {
break;
}
// 随机算法-true则为加上括号
if (randomSelective()) {
stringBuilder.append('(');
bracketsPos.add(count);
}
}
}
}
// 生成右括号
// flag 表示是否为表达式结尾
private void generateRightBracket(StringBuffer stringBuilder, boolean flag) {
if (bracketsPos.isEmpty()) {
return;
}
if (flag) {
// 如果已经到达结尾位置,进行剩余括号的闭括号操作
for (int i = 0; i < bracketsPos.size(); i++) {
if (!bracketsPos.get(i).equals(USED)) {
stringBuilder.append(')');
}
}
// 可能发生多加一个括号的情况,将其进行剔除
if (bracketsPos.size() == MAX_BRACKETS && bracketsPos.get(0).equals(bracketsPos.get(1)) && bracketsPos.get(0) != -1) {
stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
}
return;
}
if (bracketsPos.size() == MAX_BRACKETS) {
// 说明此时有两个括号
if (bracketsPos.get(0).equals(bracketsPos.get(1))) {
// 说明此时起始位置一样
if (count - bracketsPos.get(1) == 1) {
// 说明此时内括号应该结束
stringBuilder.append(')');
} else if (count - bracketsPos.get(0) == operatorsNumber - 1) {
// 说明此时内括号应该结束
stringBuilder.append(')');
bracketsPos.replaceAll(pos -> USED);
}
} else {
// 说明起始位置不同
if (count - bracketsPos.get(1) == 1) {
stringBuilder.append("))");
bracketsPos.replaceAll(pos -> USED);
}
}
} else {
if (count - bracketsPos.get(0) == operatorsNumber - 1) {
stringBuilder.append(')');
bracketsPos.set(0, -1);
return;
}
if (count - bracketsPos.get(0) == 1) {
if (randomSelective()) {
stringBuilder.append(')');
bracketsPos.set(0, -1);
}
}
}
}
}
Calculate实现具体的计算过程
public class Calculate {
public static Pattern pattern = Pattern.compile("[0-9]+\\'[0-9]+\\/[1-9][0-9]*");
//scope就是用户输入的范围限制
public static String getResult(String expression, Integer scope) {
//将所有空格去掉
expression = expression.replaceAll(" +", "");
//将表达式中所有的真分数转化成假分数
Matcher m = pattern.matcher(expression);
while(m.find())
{
expression = expression.replace(m.group(), Transform.TrueToFalse(m.group()));
}
//将中缀表达式转换成后缀表达式
expression = Transform.change(expression);
//对后缀表达式进行运算
//存放操作符的栈
Stack<String> stack = new Stack<>();
//将后缀表达式进行切割,分成多个字符串,分割之后就是单纯的数字或者运算符
String[] strings = expression.split("\\|+");
for (int i = 0; i < strings.length;) {
if (strings[i].matches("[0-9].*")) {
stack.push(strings[i]);
i++;
continue;
}
String num2 = stack.pop();
String num1 = stack.pop();
String result = cout(num1, num2, strings[i]);
if (result.equals("ERROR")) {
return result;
}
stack.push(result);
i++;
}
//使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围
String result = Transform.FinalFraction(stack.pop());
if (result.equals("ERROR")) {
return result;
}
//对结果进行校验
if (Transform.isOutRange(scope, result)) {
return "ERROR";
}
return result;
}
//判断两个数需要进行计算的方法:num1表示数字1,num2表示数字2,temp表示运算符,
private static String cout(String num1, String num2, String temp) {
String result;
//分两种方式运算,一种是整数的运算,一种是分数的运算
if (num1.matches("\\-{0,1}[0-9]+\\/\\-{0,1}[0-9]+") || num2.matches("\\-{0,1}[0-9]+\\/\\-{0,1}[0-9]+")) {
//说明是分数,调用分数运算方法
result = FractionCount(num1, num2, temp);
}
else {
//调用整数运算方法
result = IntCount(num1, num2, temp);
}
return result;
}
//num1表示数字1,num2表示数字2,temp表示运算符
private static String IntCount(String num1, String num2, String temp) {
switch (temp) {
case "+":
return String.valueOf(Integer.valueOf(num1) + Integer.valueOf(num2));
case "-":
return String.valueOf(Integer.valueOf(num1) - Integer.valueOf(num2));
case "×":
return String.valueOf(Integer.valueOf(num1) * Integer.valueOf(num2));
case "÷":
return Simplify(Integer.valueOf(num1), Integer.valueOf(num2));
default:
}
return null;
}
//将分数进行化简的式子(numerator为分子,denominator为分母)
public static String Simplify(Integer numerator, Integer denominator) {
if (denominator == 0) {
return "ERROR";
}
if (numerator == 0) {
return "0";
}
int p = Transform.getMax(numerator, denominator);
numerator /= p;
denominator /= p;
if (denominator == 1) {
return String.valueOf(numerator);
}
else {
return (numerator) + "/" + (denominator);
}
}
//分数运算:num1表示数字1,num2表示数字2,temp表示运算符
private static String FractionCount(String num1, String num2, String temp) {
//将所有的数字都化成最简分数来进行计算
int[] first = Transform.changeToFraction(num1);
int[] second = Transform.changeToFraction(num2);
int[] result = new int[2];
//获取两个分母的最小公倍数
int min = first[1] * second[1] / Transform.getMax(first[1], second[1]);
switch (temp) {
case "+":
//分子
result[0] = first[0] * min / first[1] + second[0] * min / second[1];
//分母
result[1] = min;
return Simplify(result[0], result[1]);
case "-":
//分子
result[0] = first[0] * min / first[1] - second[0] * min / second[1];
//分母
result[1] = min;
return Simplify(result[0], result[1]);
case "×":
//分子
result[0] = first[0] * second[0];
//分母
result[1] = first[1] * second[1];
return Simplify(result[0], result[1]);
case "÷":
//分子
result[0] = first[0] * second[1];
//分母
result[1] = first[1] * second[0];
return Simplify(result[0], result[1]);
}
return null;
}
}
AnswerFile实现题目以及答案文本生成,同时进行答案校对的功能
public class AnswerFile {
//获取系统当前路径
public static final String address = System.getProperty("user.dir");
public static Pattern patten = Pattern.compile("[1-9][0-9]*\\.[0-9]+(\\'{0,1}[0-9]+\\/[0-9]+){0,1}(\\/[1-9]+){0,1}");
//将答案写入文件
public static void writeFile(List answerList, boolean isAnswer) throws IOException {
File answerfile;
File exercisefile;
FileOutputStream outputStreamAnswer = null;
FileOutputStream outputStreamExercise = null;
BufferedWriter answerWriter = null;
BufferedWriter exerciseWriter = null;
if (isAnswer) {
answerfile = new File(address + "\\answer.txt");
outputStreamAnswer = new FileOutputStream(answerfile);
answerWriter = new BufferedWriter(new OutputStreamWriter(outputStreamAnswer, "UTF-8"));
if (!answerfile.exists()) {
answerfile.createNewFile();
}
} else {
exercisefile = new File(address + "\\exercise.txt");
outputStreamExercise = new FileOutputStream(exercisefile);
exerciseWriter = new BufferedWriter(new OutputStreamWriter(outputStreamExercise, "UTF-8"));
if (!exercisefile.exists()) {
exercisefile.createNewFile();
}
}
int num = 1;
for (Object o : answerList) {
String answer;
if (o instanceof String) {
answer = (String) o;
} else {
answer = ((AnswerResult) o).questionProperty().getValue();
}
answer = num++ + ". " + answer + "\r\n";
if (isAnswer){
answerWriter.write(answer);
answerWriter.flush();
}else {
exerciseWriter.write(answer);
exerciseWriter.flush();
}
}
if (isAnswer){
outputStreamAnswer.close();
answerWriter.close();
}else {
outputStreamExercise.close();
exerciseWriter.close();
}
}
//答案校对,返回的是比对结果,key是题号,value是right或error
public static Map<Integer, String> checkAnswer(File exercisefile, File answerFile) {
Controller.operationData.clear();
BufferedReader exerciseReader = null;
BufferedReader answerReader = null;
Map<Integer, String> result = new HashMap<>();
try {
if (!exercisefile.exists()) {
System.out.println("练习答案文件不存在");
return null;
}
if (!answerFile.exists()) {
System.out.println("答案文件不存在");
return null;
}
if (!exercisefile.getName().matches(".+(.txt)$") || !answerFile.getName().matches(".+(.txt)$")) {
System.out.println("文件格式不支持");
return null;
}
InputStreamReader exerciseIn = new InputStreamReader(new FileInputStream(exercisefile.getAbsolutePath()), StandardCharsets.UTF_8);
InputStreamReader answerIn = new InputStreamReader(new FileInputStream(answerFile.getAbsolutePath()), StandardCharsets.UTF_8);
exerciseReader = new BufferedReader(exerciseIn);
answerReader = new BufferedReader(answerIn);
//将题号和答案对应存储,以防止出现漏写某一道题的情况
Map<Integer, String> exerciseMap = new HashMap<>();
Map<Integer, String> answerMap = new HashMap<>();
String content = null;
while ((content = exerciseReader.readLine()) != null) {
//去除字符串的所有空格
content = content.replaceAll(" +", "");
content = content.replaceAll("\uFEFF", "");
if (!isQualified(content, false)) {
System.out.println(content);
System.out.println("文本的内容格式错误");
return null;
}
exerciseMap.put(Integer.valueOf(content.split("\\.")[0]), content.split("\\.")[1]);
}
while ((content = answerReader.readLine()) != null) {
//去除字符串的所有空格
content = content.replaceAll(" +", "");
content = content.replaceAll("\uFEFF", "");
if (!isQualified(content, true)) {
System.out.println(content);
System.out.println("文本的内容格式错误");
return null;
}
answerMap.put(Integer.valueOf(content.split("\\.")[0]), content.split("\\.")[1]);
}
exerciseReader.close();
answerReader.close();
//比对结果
for (int i = 1; i <= answerMap.size(); i++) {
if (exerciseMap.containsKey(i)) {
//将答案切割出来(格式:3+2=5)
String exercise = exerciseMap.get(i).split("=")[1];
// 将答案写入图形化界面的表格
AnswerResult answerResult = new AnswerResult();
answerResult.setQuestion(exerciseMap.get(i).split("\\=")[0]);
answerResult.setAnswerByStudent(exercise);
answerResult.setAnswerByProject(answerMap.get(i));
Controller.operationData.add(answerResult);
if (answerMap.get(i).equals(exercise)) {
//结果正确,将题号记录下来
result.put(i, "right");
} else {
result.put(i, "error");
}
}
//说明该题漏写或者错误
else {
result.put(i, "error");
}
}
} catch (IOException e) {
System.out.println("读取文件错误");
}
return result;
}
//判断文本的内容是否符合要求
private static Boolean isQualified(String content, Boolean isAnswer) {
//如果是答案的格式
if (isAnswer) {
Matcher matcher = patten.matcher(content);
if (!matcher.find()) {
return false;
}
if (matcher.group().equals(content)) {
//说明内容完全匹配
return true;
}
return false;
}
else {
//说明是表达式
String matches = "[1-9][0-9]*\\.[0-9,\\',\\/,\\+,\\-,\\(,\\),\\×,\\÷]+\\=[0-9]+";
if (content.matches(matches)) {
return true;
}
return false;
}
}
public static void main(String[] args) {
String expression = "\uFEFF1.(0÷2)×6=0";
System.out.println(expression.matches("[1-9][0-9]*\\.[0-9,\\',\\/,\\+,\\-,\\(,\\),\\×,\\÷]+\\=[0-9]+"));
}
}
六、测试运行
1、GUI生成题目: 如直接点击生成题目或参数输入错误,便会出现以上提示;

正确输入参数之后便会显示如下界面:

当点击生成题目按钮过于频繁时,则会出现以下提示:

2、 若是在控制台生成题目,同时会自动生成exercise.txt和answer.txt;若在图形界面,则只会自动生成answer.txt,用户可通过点击下载按钮来生成exercise.txt题目文件;
生成的文件如下:


执行校对答案功能:若未选择文件,则会进行响应提示

3、控制台结果显示:

GUI界面显示

七、PSP表格
|
八、项目小结
1、对业务处理有了更清晰的认识。
2、对于表达式的计算有了更深的理解。
3、对于文件的IO流更加熟悉。
4、同时对于正则表达式的使用更加熟悉。
5、对于结对编程,队友之间的配合有了进一步提升。

浙公网安备 33010602011771号