结对项目
结对项目
这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 结对实现实现一个自动生成小学四则运算题目的命令行程序 |
结对成员 | 3123004348费俊耀 && 3123004359梁鑫 |
GitHub | 费俊耀的GitHub 梁鑫的GitHub |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
Estimate | 估计这个任务需要多少时间 | 180 | 200 |
Development | 开发 | 120 | 120 |
Analysis | 需求分析 (包括学习新技术) | 20 | 20 |
Design Spec | 生成设计文档 | 20 | 15 |
Design Review | 设计复审 | 10 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 30 |
Design | 具体设计 | 60 | 60 |
Coding | 具体编码 | 120 | 100 |
Code Review | 代码复审 | 10 | 20 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 30 |
Reporting | 报告 | 20 | 20 |
Test Repor | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 10 | 15 |
合计 | 690 | 710 |
设计实现过程
一、代码组织结构
MathGenerator/
├── fraction.h // 分数核心类
├── expression.h // 表达式基类及派生类
├── generator.h // 题目生成器
├── evaluator.h // 表达式计算器
└── main.cpp // 主程序(参数处理+文件IO)
二、类关系图
三、关键函数流程
- 表达式生成流程(ProblemGenerator::generate)
- 答案校验流程(checkAnswers)
四、关键设计决策
- 1表达式树结构:
使用组合模式(Composite Pattern)处理嵌套表达式
每个BinaryExpression节点可包含子表达式
示例树结构:
÷
├── +
│ ├─ 3/4
│ └─ 1'1/2
└── 2
- 2去重机制:
规范形式(Canonical Form)生成规则:
对+和×运算进行排序:a + b → b + a(如果a > b)
带括号表达式保持原序
使用哈希集合存储规范形式
- 3运算符优先级处理:
点击查看代码
// evaluator.h中的优先级表
const map<char, int> OP_PRIORITY {
{'+', 1}, {'-', 1},
{'*', 2}, {'/', 2}
};
- 4异常处理策略:
生成时重试机制(最多100次尝试生成有效表达式)
文件操作统一检查打开状态
命令行参数严格校验
五、性能优化点
- 1内存管理:
点击查看代码
// 使用unique_ptr自动释放表达式树
unique_ptr<Expression> generate() {
return make_unique<BinaryExpression>(op, move(left), move(right));
}
- 2快速去重:
点击查看代码
unordered_set<string> generated; // O(1)查找复杂度
- 3表达式缓存:
预生成常用表达式模板(如 a + b, a - b 等)
动态调整运算符分布概率
- 性能分析
实例测试
项目小结
项目的实现过程中比预想的出现了很多错误,需要一一解决,但是两人结队处理可以分工合作,问题的解决速度比单人快上许多,总体项目的实现难度和所需时间都能有所下降