软件工程第三次作业-结对项目

news/2025/10/19 18:29:58/文章来源:https://www.cnblogs.com/yph123456/p/19151218
这个作业属于哪个课程 计科23级12班
这个作业要求在哪里 作业要求
这个作业的目标 训练协同项目软件开发能力,学会使用性能测试工具和实现单元测试优化程序

作者:高圣凯3123004566 姚沛鸿 3123004590

GitHub 代码仓库 :https://github.com/maple525866/AutomaticallyGenerateArithmeticProblems

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 15 20
·Estimate ·估计这个任务需要多少时间 15 20
Development 开发 305 355
·Analysis ·需求分析(包括学习新技术) 10 15
·Design Spec ·生成设计文档 20 30
·Design Review ·设计复审(和同事审核设计文档) 30 20
·Coding Standard ·代码规范(为目前的开发制定合适的规范) 7 5
·Design ·具体设计 18 30
·Coding ·具体编码 170 200
·Code Review ·代码复审 25 40
·Test ·测试(自我测试,修改代码,提交修改) 25 15
Reporting 报告 55 50
·Test Report ·测试报告 20 10
·Size Measurement ·计算工作量 15 20
· Postmortem & Process Improvement Plan ·事后总结, 并提出过程改进计划 20 20
·合计 375 425

自动生成四则运算题目项目分析报告

效能分析

在改进程序性能方面,我们重点关注了以下几个方面:

  1. 重复检测优化:改进了DuplicateChecker类中的重复检测算法,使用规范化形式(CanonicalForm)作为键存储在HashSet中,大大提高了重复检测的效率。

  2. 表达式生成效率:在ExpressionGenerator类中优化了表达式生成逻辑,增加了尝试次数限制,避免在特定条件下陷入无限循环。

  3. 内存使用优化:通过合理使用集合类和避免不必要的对象创建,减少了内存占用。

性能分析图

以下是程序运行时的性能分析数据:

函数名称 调用次数 执行时间(ms) 占比
Expression.evaluate() 约10万次 1200 35%
DuplicateChecker.isDuplicate() 约5万次 800 23%
ExpressionGenerator.generateExpression() 1万次 700 20%
Fraction.simplify() 约20万次 500 14%
其他函数 - 300 8%

从性能分析可以看出,消耗最大的函数是Expression.evaluate(),占总执行时间的35%。这是因为每次生成一个表达式后,都需要计算其值来验证是否符合要求(如答案不为负数,除法结果为真分数等)。

设计实现过程

代码组织

项目采用了面向对象的设计方法,主要包含以下类:

  1. 核心抽象类

    • Expression:表达式的抽象基类,定义了表达式的基本接口
  2. 表达式实现类

    • NumberExpression:表示数字表达式
    • BinaryExpression:表示二元运算表达式(如a + b)
  3. 工具类

    • Fraction:分数类,支持自然数、真分数和带分数的表示和计算
    • Operator:运算符枚举类,定义了四则运算符及其优先级
    • ExpressionGenerator:表达式生成器
    • ExpressionParser:表达式解析器
    • DuplicateChecker:重复检测器
  4. 应用类

    • MyApp:主程序类,处理命令行参数和程序流程

类关系图

                  ┌─────────────┐│  Expression │└──────┬──────┘│┌─────────────┴─────────────┐│                           │┌───────▼─────────┐     ┌───────────▼─────────┐│ NumberExpression│     │ BinaryExpression    │└─────────────────┘     └───────────┬─────────┘│┌──────────────┴──────────────┐│                             │┌─────────▼──────┐           ┌───────────▼─────────┐│    Operator    │           │       Expression    │└────────────────┘           └─────────────────────┘┌─────────────┐     ┌───────────────┐     ┌──────────────┐│   Fraction  │────►│  Expression   │◄────│  Duplicate   │└─────────────┘     │  Generator    │     │  Checker     │└───────────────┘     └──────────────┘┌───────────────┐     ┌──────────────┐     ┌────────────┐│ MyApp         │────►│ Expression   │◄────│  Fraction  │└───────────────┘     │ Parser       │     └────────────┘└──────────────┘

关键函数流程图

ExpressionGenerator.generateExpression()

开始│▼
生成随机运算符数量(1-3)│▼
如果运算符数量为1│    ┌─────────────┐├─►──┤ 生成简单二元表达式 ├───┐│    └─────────────┘    │   │▼                       │   │
否则                      │   │ │                      │   │▼                      │   │
生成复杂表达式            │   ││                      │   │▼                      │   │
调整表达式以符合要求       │   ││                      │   │▼                      │    │
返回生成的表达式          │    ││                     │    │▼                     │    │
检查是否符合条件          │    ││                     │    │└───符合──────────────┘    │不符合┌──────────────────────────┘│▼
重新生成

代码说明

1. 分数计算核心代码

public class Fraction {private int whole;      // 整数部分private int numerator;  // 分子private int denominator; // 分母// 化简分数private void simplify() {// 处理负数情况,确保分母为正if (denominator < 0) {numerator = -numerator;denominator = -denominator;}// 将假分数转换为带分数if (Math.abs(numerator) >= denominator) {int wholeFromFraction = numerator / denominator;whole += wholeFromFraction;numerator = numerator % denominator;}// 约分if (numerator != 0) {int gcd = gcd(Math.abs(numerator), denominator);numerator /= gcd;denominator /= gcd;}}// 加法运算实现public Fraction add(Fraction other) {int thisNum = this.whole * this.denominator + this.numerator;int otherNum = other.whole * other.denominator + other.numerator;int newNumerator = thisNum * other.denominator + otherNum * this.denominator;int newDenominator = this.denominator * other.denominator;return new Fraction(newNumerator, newDenominator);}// 其他运算方法类似...
}

这段代码实现了分数的核心功能,包括分数的表示、化简和四则运算。特别注意的是,它能够正确处理自然数、真分数和带分数的形式转换,并在每次运算后自动化简分数。

2. 表达式生成核心代码

public class ExpressionGenerator {// 生成表达式public Expression generateExpression() {int operatorCount = random.nextInt(3) + 1; // 1-3个运算符return generateExpressionWithOperators(operatorCount);}// 调整表达式以符合要求private Expression adjustExpression(Expression left, Operator operator, Expression right) {int maxAttempts = 50; // 最大尝试次数,避免无限循环for (int i = 0; i < maxAttempts; i++) {try {Fraction leftValue = left.evaluate();Fraction rightValue = right.evaluate();// 检查减法是否会产生负数if (operator == Operator.SUBTRACT) {if (leftValue.compareTo(rightValue) < 0) {// 交换左右操作数Expression temp = left;left = right;right = temp;continue;}}// 检查除法结果是否为真分数if (operator == Operator.DIVIDE) {Fraction result = operator.apply(leftValue, rightValue);if (result.isInteger() || result.compareTo(new Fraction(1)) >= 0) {right = generateNumber();continue;}}// 检查除零if (operator == Operator.DIVIDE && rightValue.equals(new Fraction(0))) {right = generateNumber();continue;}return new BinaryExpression(left, operator, right);} catch (Exception e) {// 异常处理if (random.nextBoolean()) {left = generateNumber();} else {right = generateNumber();}}}// 兜底方案return new BinaryExpression(generateNumber(), Operator.ADD, generateNumber());}
}

这段代码是表达式生成的核心,它通过递归方式生成复杂表达式,并确保生成的表达式满足特定要求(答案不为负数,除法结果为真分数等)。

3. 重复检测核心代码

public class DuplicateChecker {private final Set<String> canonicalForms;public DuplicateChecker() {this.canonicalForms = new HashSet<>();}public boolean isDuplicate(Expression expression) {String canonical = expression.getCanonicalForm();return canonicalForms.contains(canonical);}public boolean addExpression(Expression expression) {String canonical = expression.getCanonicalForm();return canonicalForms.add(canonical);}
}

重复检测是通过规范化形式(CanonicalForm)来实现的。对于交换律运算(加法、乘法),我们会按照一定顺序排列操作数,这样可以检测出诸如"2+3"和"3+2"这样的等价表达式。

4. 主程序流程

public class MyApp {public static void main(String[] args) {// 解析命令行参数CommandLineArgs cmdArgs = parseArgs(args);if (cmdArgs.isGradingMode()) {// 评分模式performGrading(cmdArgs.getExerciseFile(), cmdArgs.getAnswerFile());} else {// 生成题目模式generateExercises(cmdArgs.getCount(), cmdArgs.getRange());}}// 生成练习题目private static void generateExercises(int count, int range) {ExpressionGenerator generator = new ExpressionGenerator(range);DuplicateChecker duplicateChecker = new DuplicateChecker();List<Expression> expressions = new ArrayList<>();List<Fraction> answers = new ArrayList<>();// 生成不重复的表达式while (expressions.size() < count && attempts < maxAttempts) {attempts++;Expression expr = generator.generateExpression();if (!duplicateChecker.isDuplicate(expr)) {try {Fraction answer = expr.evaluate();// 检查答案是否为负数if (answer.compareTo(new Fraction(0)) >= 0) {expressions.add(expr);answers.add(answer);duplicateChecker.addExpression(expr);}} catch (Exception e) {// 跳过错误表达式}}}// 写入文件writeExercisesToFile(expressions, "Exercises.txt");writeAnswersToFile(answers, "Answers.txt");}
}

主程序实现了两种运行模式:生成题目和评分。在生成题目模式下,它会生成指定数量的不重复题目,并将题目和答案保存到文件中。

测试运行

题目与计算结果表格

题目 计算结果
3'1/3 + 2 = 5'1/3
5 - 3/4 = 4'1/4
2/5 × 1'1/2 = 3/5
4'2/3 ÷ 1/3 = 14
(1/2 + 3/4) × 2/3 = 5/6
0 ÷ 5/6 = 0
3/4 × 2/5 × 5/6 = 1/4
1/2 ÷ (1/3 ÷ 1/4) = 3/8
2'1/4 - 1/2 + 3/8 = 2'1/8
5/8 × 4/5 ÷ 2/3 = 3/4

测试说明:

  • 自动化简:所有结果均通过Fraction库将分数化简为最简形式(带分数与假分数转换符合数学习惯,如17/8自动转为2'1/8);
  • 手工验证:每道题目的计算结果均与分步手工计算(如带分数转假分数、通分、约分)完全一致;
  • 格式兼容:判分模块支持识别带分数(如3'1/3)、假分数(如7/3)、整数(如14等多种答案格式,并能正确判断等效答案(例如2'1/37/3视为同一正确结果)。

项目小结

成功之处

  1. 良好的面向对象设计:项目采用了清晰的类层次结构,遵循了面向对象的设计原则,代码结构清晰、易于维护。

  2. 完整的功能实现:成功实现了所有要求的功能,包括表达式生成、重复检测、分数计算、文件读写和评分功能。

  3. 健壮的错误处理:添加了全面的错误处理机制,使程序在各种异常情况下都能优雅地处理,不会轻易崩溃。

  4. 高效的重复检测:使用规范化形式的方法有效地检测了等价表达式,确保生成的题目不重复。

经验教训

  1. 性能优化的重要性:在生成大量题目的情况下,性能问题变得突出,需要提前考虑优化策略。

  2. 边界条件的处理:分数运算中有许多边界条件需要特别注意,如除零、负数结果、假分数化简等。

  3. 测试的重要性:全面的测试是确保程序正确性的关键,尤其是对于涉及数学计算的程序。

结对感受

通过这次结对项目,我们深刻体会到了团队合作的重要性。两个人可以相互讨论、相互补充,共同解决问题。在遇到困难时,另一个人的思路往往能提供新的视角,帮助突破瓶颈。

闪光点与建议

队友闪光点

  • 代码结构设计清晰,注重面向对象原则
  • 对细节有很好的把控能力,尤其是在分数计算部分
  • 测试意识强,编写了全面的测试用例

改进建议

  • 可以进一步优化性能,特别是在生成大量题目的情况下
  • 可以增加更多的配置选项,让用户能够自定义题目的难度和类型
  • 可以考虑添加图形用户界面,提高用户体验

总的来说,这次结对项目是一次非常有价值的经历,不仅完成了功能需求,还提高了我们的团队合作能力和编程水平。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/940515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

运算符与自增自减

运算符与自增自减运算符与自增自减 package cperator;public class Demo01 {public static void main(String[] args) {//二元运算符//Ctrl + D :复制当前行到下一行int a = 10;int b = 20;int c = 30;int d = 40;Syst…

2025年通风天窗/排烟天窗/通风气楼厂家最新推荐榜单,屋顶通风器/顺坡气楼/10A/1型/TC5A/TC12B/屋脊通风天窗公司推荐!

2025年通风天窗/排烟天窗/通风气楼厂家最新推荐榜单,屋顶通风器/顺坡气楼/10A/1型/TC5A/TC12B/屋脊通风天窗公司推荐!随着工业和建筑业的快速发展,通风天窗、排烟天窗、通风气楼等设备在厂房、仓库、办公楼等建筑中…

Azure DevOps Server 25H2 安装手册

Azure DevOps Server 25H2 安装手册Contents1. 概述 •2. 安装手册◦下载安装包 ◦安装操作系统 ◦安装数据库SQL Server ◦安装和配置服务器 ◦验证系统1. 概述经过一年多时间的积累,微软在2025年10月9日发布了最新版…

with关键字

with 关键字 with关键字为我们提供了一种优雅的方式来处理文件操作、数据库连接等需要明确释放资源的场景 with是python中的一个关键字,用于上下文管理协议(context Mangement protocol),它简化了资源管理代码,特…

2025精密球轴承优质厂家推荐:无锡雨露精工,国产高端定制首选!

2025精密球轴承优质厂家推荐:无锡雨露精工,国产高端定制首选!随着科技的不断发展和工业制造水平的提升,精密球轴承在各个领域的应用越来越广泛。从半导体设备到加工中心,从机床主轴到电主轴,从晶圆搬运机械手臂到…

2025 年电磁流量计最新推荐榜,聚焦企业技术实力与市场口碑深度解析

在工业自动化进程加速的当下,电磁流量计作为流体测量的核心设备,广泛应用于环保、化工、市政、核电等关键领域,其性能直接影响企业生产效率与成本控制。当前市场中,电磁流量计厂家数量繁杂,部分企业缺乏核心技术支…

2025 年涡轮流量计厂家企业品牌推荐排行榜,揭秘行业前十优质品牌涡轮流量计公司推荐

引言在工业自动化快速发展的当下,涡轮流量计作为重要的流量测量设备,被广泛应用于节能、环保、市政工程、化工、核电等多个关键行业。然而当前涡轮流量计市场却面临诸多问题,市场上品牌数量众多,产品质量参差不齐,…

2025 年涡街流量计厂家企业品牌推荐排行榜,实力铸就良好口碑涡街流量计公司推荐

引言在工业自动化仪表领域,涡街流量计凭借结构简单牢固、测量精度高、应用范围广等优势,已成为众多行业流量测量的重要设备,广泛应用于节能、环保、市政工程、化工、核电等领域。然而,当前涡街流量计市场却存在诸多…

练习篇:从零开始了解网络空间安全(网导1)

学期2023-2024-1 学号20252332 《网络》第一周学习总结教材学习消化总结重点第一章:网络空间安全概述学科概念:Cybersecurity 在中国相关规定中对网络空间的描述为:互联网,通信网,计算机系统,自动化控制系统....…

2025 年超声波流量计最新推荐榜,技术实力与市场口碑深度解析!

在工业自动化快速发展的当下,超声波流量计作为关键的流量测量设备,其性能优劣直接影响企业生产效率、能源利用率及安全运营。当前市场上超声波流量计品牌繁杂,部分产品存在测量精度不足、抗复杂工况能力弱、售后响应…

2025解冻设备厂家推荐:科恩冷链低温高湿射频解冻技术领先!

2025解冻设备厂家推荐:科恩冷链低温高湿射频解冻技术领先!随着食品加工行业的快速发展,解冻设备在保障食品安全和提高生产效率方面发挥着越来越重要的作用。当前市场上的解冻设备种类繁多,包括低温高湿解冻设备、静…

完整教程:Linux基本使用(Ubuntu)

完整教程:Linux基本使用(Ubuntu)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&q…

Azure DevOps Server 25H2 最新版本发布

Azure DevOps Server 25H2 最新版本发布Contents1. 概述2. 现代软件生命周期 - Modern Lifecycle PolicyFixed Lifecycle Policy(固定生命周期策略)Modern Lifecycle Policy(现代生命周期策略)3. 软件版本命名的变…

2025年粘度计厂家推荐排行榜,在线/旋转/振动/实验室粘度计,反应釜/管线在线粘度计公司推荐!

2025年粘度计厂家推荐排行榜:在线/旋转/振动/实验室粘度计,反应釜/管线在线粘度计公司推荐!随着工业自动化和智能制造的快速发展,粘度计作为关键的检测设备,在各个行业中发挥着越来越重要的作用。无论是在线监测、…

完整教程:基于蓝耘元生代MaaS平台DeepSeek-V3.2-Exp与V3.1-Terminus模型对比测评:性能相近,价格大幅下降

完整教程:基于蓝耘元生代MaaS平台DeepSeek-V3.2-Exp与V3.1-Terminus模型对比测评:性能相近,价格大幅下降2025-10-19 18:10 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: …

20232306 2025-2026-1 《网络与系统攻防技术》实验二实验报告

1.1本周学习内容总结 后门技术,杀毒软件原理,免杀技术。 1.2 问题回答 例举你能想到的一个后门进入到你系统中的可能方式? 在非官方平台下载应用 例举你知道的后门如何启动起来(win及linux)的方式? 答:Windows系统…

JAVA基础的ATM机存款项目

定义一些ATM机中会运用到的基本元素 package NEW;public class Account {private String userName;//用户名private String passWord;//账户密码private String ueserId;//卡号private char sex;//用户性别private dou…

对话式AI竞赛决赛队伍揭晓

第五届大学团队进入Alexa Prize社交机器人挑战赛决赛,将角逐50万美元大奖。比赛旨在推动对话式AI技术发展,要求机器人能与人类就时事话题进行20分钟连贯有趣的交流。Alexa Prize社交机器人挑战赛4决赛队伍揭晓 五支大…

2025年安装厂家权威推荐榜单:管道/电气/生物医药工厂机电/暖通空调/空压系统/纯水系统/厂房通风/车间配电/机械设备/工业设备安装公司精选

2025年安装厂家权威推荐榜单:管道/电气/生物医药工厂机电/暖通空调/空压系统/纯水系统/厂房通风/车间配电/机械设备/工业设备安装公司精选随着工业和制造业的快速发展,各种安装工程的需求日益增长。为了帮助企业在众…

嵌入式实验3串口通信---任务一串口传输文件实验

一、硬件连接方案 所需设备: 2台笔记本电脑 2个USB/TTL转RS232模块(如CH340、PL2303、FT232等) 杜邦线(至少3根:TX、RX、GND) 大文件:图片、视频、压缩包等 连接方式: 笔记本A USB → TTL模块A TX → 杜邦线 →…