作业三

姓名 学号 仓库地址
陈浩龙 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;
}

测试

image

image
image
image

总结

通过本次的结对项目,我们不仅深入了解了如何进行高效的项目合作,还通过互相分享各自的经验和知识,极大地提升了团队的整体能力。在合作过程中,我们认识到自身的不足,并通过技术上的互补,成功克服了许多挑战。同时,我们也深刻意识到,在结对合作中,频繁的交流与讨论是至关重要的,它不仅帮助我们更好地理解彼此的想法,还能激发更多的创新思路,从而推动项目的顺利进行。此外,我们还学会了如何在合作中保持开放的心态,积极倾听对方的意见,并在遇到分歧时通过有效的沟通达成共识。

posted @ 2025-03-21 13:59  Kim_NorthFroce  阅读(16)  评论(0)    收藏  举报