作业三
姓名 | 学号 | 仓库地址 |
---|---|---|
陈浩龙 | 3123004132 | https://github.com/unhbbh/unhbbh/tree/main/JavaFiles |
朱效民 | 3123007654 | https://github.com/KIMNorthFroce/3123007654/tree/master/JavaFiles |
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023/homework/13326 |
这个作业的目标 | <学习如何合作完成项目> |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 预估耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
· Estimate | · 估计这个任务需要多少时间 | 60 | 80 |
Development | 开发 | ||
· Analysis | · 需求分析 (包括学习新技术) | 90 | 60 |
· Design Spec | · 生成设计文档 | 40 | 45 |
· Design Review | · 设计复审 | 40 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 60 | 60 |
· Design | · 具体设计 | 120 | 130 |
· Coding | · 具体编码 | 90 | 60 |
· Code Review | · 代码复审 | 60 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 90 | 90 |
Reporting | 报告 | ||
· Test Repor | · 测试报告 | 60 | 40 |
· Size Measurement | · 计算工作量 | 30 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 80 |
· 合计 | 800 | 765 |
设计实现过程:
Main
├─ 解析命令行参数
├─ 若为生成模式:
│ ├─ 调用 ExpressionGenerator.generateRandomExpression() 递归生成 Expression 对象
│ ├─ 调用 AnswerEvaluator.evaluateToString() 得到表达式结果(调用 Expression.evaluate() → Fraction运算)
│ └─ 调用 FileManager.writeToFile() 写入 Exercises.txt 和 Answers.txt
└─ 若为批改模式:
├─ 调用 FileManager.readFile() 读取题目和答案文件
├─ 对每道题调用 ExpressionParser.parse() 解析表达式
├─ 调用 AnswerEvaluator.evaluateToString() 得到正确答案
├─ 对比用户答案(Grader.parseUserAnswer())统计正确和错误题号
└─ 调用 FileManager.writeToFile() 写入 Grade.txt
关键代码示例:
Main 方法与命令行解析
点击查看代码
public static void main(String[] args) {
// 当参数为空时,输出帮助信息
if (args.length == 0) {
printHelp();
System.exit(1);
}
// 生成题目模式:要求同时给出 -n 和 -r 参数
if (hasParam(args, "-n") && hasParam(args, "-r")) {
int count = Integer.parseInt(getParamValue(args, "-n"));
int range = Integer.parseInt(getParamValue(args, "-r"));
ExpressionGenerator generator = new ExpressionGenerator(range);
Set<String> exerciseSet = new HashSet<>();
List<String> exercises = new ArrayList<>();
List<String> answers = new ArrayList<>();
int index = 1;
// 循环生成题目直到达到所需数量
while (exercises.size() < count) {
Expression exp = generator.generateRandomExpression(0);
String normalized = exp.getNormalizedString();
if (!exerciseSet.contains(normalized)) {
exerciseSet.add(normalized);
exercises.add(index + ". " + exp.toString() + " =");
answers.add(index + ". " + AnswerEvaluator.evaluateToString(exp));
index++;
}
}
FileManager.writeToFile("Exercises.txt", exercises);
FileManager.writeToFile("Answers.txt", answers);
System.out.println("生成题目成功,生成的题目存放在 Exercises.txt,答案存放在 Answers.txt");
} else if (hasParam(args, "-e") && hasParam(args, "-a")) {
// 批改模式,根据题目文件和答案文件生成成绩
String exerFile = getParamValue(args, "-e");
String ansFile = getParamValue(args, "-a");
Grader grader = new Grader(exerFile, ansFile);
grader.grade();
System.out.println("批改完成,结果存放在 Grade.txt");
} else {
printHelp();
System.exit(1);
}
}
ExpressionGenerator.generateRandomExpression()用于生成对象
点击查看代码
public Expression generateRandomExpression(int level) {
// 运算符个数达到上限或随机决定返回数字表达式
if (level >= 3 || rand.nextBoolean()) {
return generateNumber();
} else {
char operator = randomOperator();
Expression left, right;
if (operator == '-') {
left = generateRandomExpression(level + 1);
// 确保减法结果不为负,左值大于等于右值
do {
right = generateRandomExpression(level + 1);
} while (AnswerEvaluator.evaluate(left).compareTo(AnswerEvaluator.evaluate(right)) < 0);
} else if (operator == '÷') {
left = generateRandomExpression(level + 1);
do {
right = generateRandomExpression(level + 1);
} while (AnswerEvaluator.evaluate(right).isZero());
} else {
left = generateRandomExpression(level + 1);
right = generateRandomExpression(level + 1);
}
return new BinaryExpression(left, right, operator);
}
}
ExpressionParser.parse() 与 tokenize()用于提取、解析表达式
点击查看代码
public static Expression parse(String s) {
tokens = tokenize(s);
pos = 0;
return parseExpression();
}
private static List<String> tokenize(String s) {
List<String> result = new ArrayList<>();
// 正则表达式提取带分数、分数、自然数和运算符
Pattern pattern = Pattern.compile("\\d+’\\d+/\\d+|\\d+/\\d+|\\d+|[+\\-×÷()]");
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
result.add(matcher.group());
}
return result;
}
测试
总结
通过本次的结对项目,我们不仅深入了解了如何进行高效的项目合作,还通过互相分享各自的经验和知识,极大地提升了团队的整体能力。在合作过程中,我们认识到自身的不足,并通过技术上的互补,成功克服了许多挑战。同时,我们也深刻意识到,在结对合作中,频繁的交流与讨论是至关重要的,它不仅帮助我们更好地理解彼此的想法,还能激发更多的创新思路,从而推动项目的顺利进行。此外,我们还学会了如何在合作中保持开放的心态,积极倾听对方的意见,并在遇到分歧时通过有效的沟通达成共识。