结对项目信息
课程信息
项目 | 内容 |
---|---|
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience |
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13470 |
这个作业的目标 | 设计一个自动生成小学四则运算题目的命令行程序 |
个人信息
姓名 | 学号 |
---|---|
邓莹 | 3223004684 |
阿迪拉·米吉提 | 3223004683 |
GitHub地址
https://github.com/DY0310/Myapp_3223004684
一、PSP2.1表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 20 |
Estimate | 估计这个任务需要多少时间 | 10 | 20 |
Development | 开发 | 400 | 600 |
Analysis | 需求分析 (包括学习新技术) | 60 | 90 |
Design Spec | 生成设计文档 | 10 | 15 |
Design Review | 设计复审 (和同事审核设计文档) | 10 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 15 | 15 |
Design | 具体设计 | 20 | 30 |
Coding | 具体编码 | 180 | 240 |
Code Review | 代码复审 | 20 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 240 |
Reporting | 报告 | 30 | 60 |
Test Report | 测试报告 | 20 | 30 |
Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 945 | 1440 |
二、效能分析
性能分析
改进思路
-
重复检测优化:原设计中用
std::set
存储完整题目字符串(表达式+答案),键值过长导致哈希计算耗时;优化后将表达式转为"标准化字符串"(如去冗余括号(1+2)
→1+2
),减少键值长度,查询效率提升约30%。 -
随机数生成优化:原代码中
random_device
在部分环境下会生成伪随机种子,改为固定种子+线程局部存储(TLS),避免多线程下的竞争,生成速度提升了。 -
表达式验证剪枝:原验证逻辑在生成后才检查运算符数量,优化为在
generateExpression
中强制控制运算符计数,减少无效尝试,失败重试率下降了。
三、设计实现过程
项目采用了"类+工具函数"的模块化设计,下面是函数类的关系图:
MyappGenerator (静态类)
↓
Fraction (分数类)
↓
generateProblems(生成批量题目) →generateSingleProblem(生成单道不重复题目) → generateExpression(递归生成表达式) → generateNumber(生成随机数字)
交互界面模块:
Fraction类函数流程图:
整个程序流程图:
四、代码说明
关键代码1:Fraction类(分数处理)
思路:封装分数运算,自动约分,支持四则运算
关键代码2:generateExpression(表达式生成算法)
思路:递归生成表达式树,加权随机选择运算符,处理边界条件。
关键代码3:交互界面系统
思路:提供双重接口,既支持系统的命令行参数方式,也提供友好的图形化交互界面,提升用户体验。
关键代码4:题目验证
思路:确保生成的题目符合小学数学要求
五、测试运行
测试用例编号 | 输入参数 | 预期结果 | 实际结果 | 测试目的 |
---|---|---|---|---|
1 | -n 1 -r 5 | 生成1道题,数值≤4,1-3个运算符,结果非负 | 示例:"3 + 1/2 =",答案"3.5" | 基础功能验证 |
2 | -n 100 -r 10 | 100道题无重复,除法结果为真分数(如"2 ÷ 3 =",答案"2/3") | 无重复,除法结果均为真分数 | 去重与除法规则验证 |
3 | -n 5 -r 2 | 数值≤1,无分数(因r-1=1<2),示例:"1 - 0 =",答案"1" | 所有题目为整数,无分数 | 范围边界验证(r=2) |
4 | -n 10 -r 0 | 报错:"范围参数必须大于等于2" | 正确报错 | 参数合法性校验 |
5 | -n -5 -r 10 | 报错:"必须提供 -n 和 -r 参数"(n≤0) | 正确报错 | 负数值参数校验 |
6 | -n 1000 -r 50 | 生成进度每1000道打印一次,无崩溃,Exercises.txt和Answers.txt行数一致 | 进度正常打印,文件行数均为1000 | 大批量生成稳定性验证 |
7 | -n 1 -r 10 | 带括号题目(40%概率),示例:"(2'1/3 + 5) - 3 =",答案"4'1/3" | 成功生成带括号题目 | 括号生成逻辑验证 |
8 | -n 1 -r 10 | 减法无负数,示例:"5 - 2'1/2 =",答案"2'1/2"(不会出现"2'1/2 - 5") | 所有减法题左操作数≥右操作数 | 减法非负规则验证 |
9 | -n 2 -r 10 | 相同表达式不同括号视为重复(如"(1+2)+3"和"1+(2+3)"视为同一题) | 第二道题自动生成不同表达式,无重复 | 重复检测逻辑验证 |
10 | -h | 显示帮助信息(用法、示例、说明) | 帮助信息完整,格式正确 | 帮助功能验证 |
程序正确性保证
逻辑正确性:所有运算(加减乘除)通过Fraction类的化简和边界处理(如减法非负、除法真分数)确保结果合法。
无重复性:通过std::set存储标准化后的题目键值,确保相同逻辑的题目不重复生成。
参数校验:对n≤0、r<2等非法输入进行拦截,避免程序崩溃。
文件一致性:生成的Exercises.txt和Answers.txt行数严格相等,确保每道题对应唯一答案。
六、项目小结
1. 结对开发得失
成功点:
-
分工明确:一人负责Fraction类和运算逻辑,一人负责表达式生成和去重,减少代码冲突。
-
交叉测试:两人分别设计测试用例,覆盖对方未考虑的边界(如r=2时无分数),提升正确性。
-
完整实现了四则运算题目生成功能,支持分数和带分数运算;确保题目符合小学数学要求,代码结构清晰,易于维护。
4.用户体验优化:添加了请屏、进度显示、题目预览等优化功能。
经验教训: -
递归深度控制:初期未限制递归深度,导致栈溢出。
-
分数运算精度:需要仔细处理分数化简和运算。
-
错误处理:完善的参数验证很重要。
2. 结对感受
两人互补性强:逻辑严谨的成员负责核心运算,细心的成员负责边界校验和测试,效率高于单人开发。
沟通成本可控:通过即时同步代码进度(如每完成一个函数同步一次),避免了后期大规模修改。
邓莹的闪光点:对分数化简和运算的边界处理考虑周全(如分母为负时的符号调整),减少了后期bug;设计了友好的用户交好界面,提升了程序应用性。
阿迪拉的闪光点:设计了"重试+保底"机制,避免了生成失败导致的死循环。