第3次软工作业
肖鹏天 3121005314
李 锷 3121005298
结对项目github链接
一、作业概述
| 这个作业属于哪个课程 | 计科4班软件工程 |
|---|---|
| 这个作业要求在哪里 | 结对项目 |
| 这个作业的目标 | 结对设计实现一个自动生成小学四则运算题目的命令行程序 |
二、PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 10 | 15 |
| · Estimate | · 估计这个任务需要多少时间 | 10 | 15 |
| Development | 开发 | 620 | 765 |
| · Analysis | · 需求分析 (包括学习新技术) | 60 | 70 |
| · Design Spec | · 生成设计文档 | 30 | 30 |
| · Design Review | · 设计复审 (和同事审核设计文档) | 30 | 45 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 25 |
| · Design | · 具体设计 | 150 | 180 |
| · Coding | · 具体编码 | 240 | 300 |
| · Code Review | · 代码复审 | 60 | 75 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 30 | 40 |
| Reporting | 报告 | 80 | 100 |
| · Test Report | · 测试报告 | 30 | 30 |
| · Size Measurement | · 计算工作量 | 30 | 30 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 40 |
| 合计 | 710 | 880 |
三、模块设计
3.1 算法流程图
- 3.1.1 总体流程图
![]()
- 3.1.2 newExam(算式生成)方法流程图
![]()
- 3.1.3 isEquivalentQuestion(算式查重)方法流程图
![]()
3.2 项目结构

3.3 核心代码
- 3.3.1 newExam(算式生成)方法
public static List<String> newExam() {
List<String> questions = new ArrayList<>();
int count = 0;
while (count < NUM_OF_QUESTIONS) {
int a = random.nextInt(MAX_NUMBER - MIN_NUMBER + 1) + MIN_NUMBER;
//生成MIN_NUMBER和MAX_NUMBER之间的随机整数
int b = random.nextInt(MAX_NUMBER - MIN_NUMBER + 1) + MIN_NUMBER;
char operator = OPERATORS[random.nextInt(OPERATORS_COUNT)];
//随机生成运算符
if (operator == '/' && (b == 0 || a % b != 0)) {
//除法的除数不能为0
continue;
}
if (operator == '-' && (a < b)) {
continue;
}
String question = "(" + (count + 1) + "):" + a + " " + operator + " " + b + " = ";
//式子表示的格式
boolean isDuplicate = false;
for (String q : questions) {
//遍历questions列表检查题目是否重复
if (isEquivalentQuestion(question, q)) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
questions.add(question);
//如果题目不重复,则把题目加入questions列表
if (count < 9) {
//用于文本序号的规范表示,当序号为1到9之间的数时,将序号表示成01、02...
answer.append("0");
test.append("0");
}
answer.append((count + 1) + ". " + intAnswer(operator, a, b) + "\n");
//将结果添加到answer字符串末尾
test.append((count + 1) + ". " + a + " " + operator + " " + b + " = " + "\n");
}
count++;
}
return questions;
}
- 3.3.2 isEquivalentQuestion(算式查重)方法
for (int i = 1; i < tokens1.length - 1; i += 2) {
//判断两个式子是否等价,由于两个运算符号之间间隔一个数,故i在每次循环之后需要加2
if (tokens1[i].equals("+")) {
numPlus1++;
plusPositions1.add(i);
} else if (tokens1[i].equals("*")) {
numTimes1++;
timesPositions1.add(i);
}
if (tokens2[i].equals("+")) {
numPlus2++;
plusPositions2.add(i);
} else if (tokens2[i].equals("*")) {
numTimes2++;
timesPositions2.add(i);
}
}
if (numPlus1 != numPlus2 || numTimes1 != numTimes2) {
//若两个式子的运算符号个数不相同,则两个式子不等价
return false;
}
if (!plusPositions1.equals(plusPositions2) || !timesPositions1.equals(timesPositions2)) {
//若两个式子的运算符号个数相同,但出现的位置不一样,两个式子也不等价
return false;
}
for (int i = 0; i < tokens1.length; i += 2) {
//两个式子的运算符号个数及位置一致,检查运算数
if (!tokens1[i].equals(tokens2[i])) {
return false;
}
}
四、程序演示
- 题目文本 Exercises.txt 示例输出结果
![]()
- 答案文本 Answers.txt 示例输出结果
![]()
- 练习文本 MyAnswer.txt 示例(自行填入)
![]()
- 批改文本 Grade.txt 输出结果
![]()
五、性能分析
5.1 概览

5.2 实时内存

从上图可以看出,在该程序中,字符数组char[ ]和String类占用最多的内存,这主要与运算符号、题目文本及答案文本等的生成和文件写入时,调用了一系列List类方法、String类方法有关。
5.3 代码覆盖率

六、项目总结
这是我们第一次进行结对程序设计的任务,这个过程让我们对结对编程有了更深刻的理解。
- 结对编程的方式可以充分发挥两个人的优势,合理分配任务,使程序设计更有效率、有条不紊地进行。
- 由于编写程序是两人共同进行,所以总是能及时地发现队友的错误,这有效地减小了处理bug的时间,使得最终设计出来的程序更加严谨。
- 在结对设计程序的过程中,两个成员会萌发出各种各样的想法,并在共同努力之下,将灵感付诸实践,赋予项目一些创新之处。
- 沟通的过程同样也是学习的过程,在本次结对编程中,通过与队友的交流我学到了一些宝贵的经验与知识。
- 当队友的想法取得一定成果时,彼此之间都会及时地给予肯定,共同开发项目的同时也增进了友谊,学会倾听与尊重他人,提高了团队协作的能力。







浙公网安备 33010602011771号