结对项目
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/ |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230 |
这个作业的目标 | 实现一个自动生成小学四则运算题目的命令行程序 |
一、成员个人信息
姓名 | 学号 |
---|---|
龙杜冰 | 3122004578 |
二、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 960 | 1170 |
· Analysis | · 需求分析 (包括学习新技术) | 55 | 60 |
· Design Spec | · 生成设计文档 | 25 | 50 |
· Design Review | · 设计复审 | 5 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 5 | 10 |
· Design | · 具体设计 | 130 | 220 |
· Coding | · 具体编码 | 600 | 700 |
· Code Review | · 代码复审 | 20 | 40 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 80 |
Reporting | 报告 | 120 | 165 |
· Test Report | · 测试报告 | 75 | 115 |
· Size Measurement | · 计算工作量 | 25 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
合计 | 1110 | 1365 |
三、效能分析
-
测试生成题目
-
CPU负载
-
性能优化
1.减少过程调用
2.减少内存引用和访问
四、实现过程
-
需求分析
-
项目结构
五、代码说明
- main
public class MathExercise {
public static void main(String[] args) {
// 解析命令行参数
System.out.println("Usage: java MathExercise [-n numQuestions] [-r range]");
Scanner input=new Scanner(System.in);
System.out.println("请输入生成题目的数量:");
int numQuestions = input.nextInt();
Scanner input2=new Scanner(System.in);
System.out.println("请输入题目中数值的范围:");
int range = input.nextInt();
// int numQuestions = 10;
// int range = 10;
boolean generateExercises = true;
boolean gradeExercises = false;
String exerciseFile ="exercises.txt";;
String answerFile = "answers.txt";
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "-n":
numQuestions = Integer.parseInt(args[++i]);
break;
case "-r":
range = Integer.parseInt(args[++i]);
break;
case "-e":
exerciseFile = args[++i];
generateExercises = false;
break;
case "-a":
answerFile = args[++i];
gradeExercises = true;
break;
}
}
// 生成题目和答案
List<String> exercises = new ArrayList<>();
List<String> answers = new ArrayList<>();
if (generateExercises) {
Random random = new Random();
for (int i = 0; i < numQuestions; i++) {
String exercise = generateExercise(random, range);
String answer = evaluateExpression(exercise);
exercises.add(exercise);
answers.add(answer);
}
}
// 打印题目和答案
for (int i = 0; i < numQuestions; i++) {
System.out.println("Exercise " + (i + 1) + ": " + exercises.get(i));
System.out.println("Answer " + (i + 1) + ": " + answers.get(i));
}
// 写入题目和答案到文件
if (generateExercises) {
try {
FileWriter exerciseWriter = new FileWriter("Exercises.txt");
FileWriter answerWriter = new FileWriter("Answers.txt");
for (String exercise : exercises) {
exerciseWriter.write(exercise + "\n");
}
for (String answer : answers) {
answerWriter.write(answer + "\n");
}
exerciseWriter.close();
answerWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (true) {
if (exerciseFile == null || answerFile == null) {
System.out.println("Exercise file or answer file not specified.");
return;
}
try {
Scanner exerciseScanner = new Scanner(new File(exerciseFile));
Scanner answerScanner = new Scanner(new File(answerFile));
List<String> correctAnswers = new ArrayList<>();
List<String> wrongAnswers = new ArrayList<>();
int questionNumber = 1;
while (exerciseScanner.hasNextLine() && answerScanner.hasNextLine()) {
String exercise = exerciseScanner.nextLine();
String answer = answerScanner.nextLine();
String userAnswer = evaluateExpression(exercise);
if (userAnswer.equals(answer)) {
correctAnswers.add(String.valueOf(questionNumber));
} else {
wrongAnswers.add(String.valueOf(questionNumber));
}
questionNumber++;
}
FileWriter gradeWriter = new FileWriter("Grade.txt");
gradeWriter.write("Correct: " + correctAnswers.size() + " (" + String.join(", ", correctAnswers) + ")\n");
gradeWriter.write("Wrong: " + wrongAnswers.size() + " (" + String.join(", ", wrongAnswers) + ")\n");
gradeWriter.close();
System.out.println("Grade file created successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}}
- 生成四则运算题目
public static String generateExercise(Random random, int range) {
int a = random.nextInt(range) + 1;
int b = random.nextInt(range) + 1;
int operator = random.nextInt(4);
String exercise;
switch (operator) {
case 0:
exercise = a + " + " + b;
break;
case 1:
exercise = a + " - " + b;
break;
case 2:
exercise = a + " * " + b;
break;
case 3:
exercise = a + " / " + b;
break;
default:
exercise = "";
}
return exercise;
}
- 计算四则运算表达式的结果
public static String evaluateExpression(String expression) {
Stack<Integer> operandStack = new Stack<>();
Stack<Character> operatorStack = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
char ch = expression.charAt(i);
if (ch == ' ')
continue;
if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
while (!operatorStack.isEmpty() && precedence(operatorStack.peek()) >= precedence(ch)) {
processAnOperator(operandStack, operatorStack);
}
operatorStack.push(ch);
} else if (ch >= '0' && ch <= '9') {
StringBuilder operand = new StringBuilder();
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
operand.append(expression.charAt(i++));
}
i--;
operandStack.push(Integer.parseInt(operand.toString()));
}
}
while (!operatorStack.isEmpty()) {
processAnOperator(operandStack, operatorStack);
}
return operandStack.pop().toString();
}
- 处理运算符
public static void processAnOperator(Stack<Integer> operandStack, Stack<Character> operatorStack) {
char operator = operatorStack.pop();
int operand1 = operandStack.pop();
int operand2 = operandStack.pop();
switch (operator) {
case '+':
operandStack.push(operand2 + operand1);
break;
case '-':
operandStack.push(operand2 - operand1);
break;
case '*':
operandStack.push(operand2 * operand1);
break;
case '/':
operandStack.push(operand2 / operand1);
break;
}
}
- 运算符优先级
public static int precedence(char operator) {
if (operator == '+' || operator == '-')
return 1;
else if (operator == '*' || operator == '/')
return 2;
else
return 0;
}}
六、测试运行
-
测试生成习题
-
测试答案