软工结对项目
这个作业属于哪个课程 | 结对项目 |
---|---|
这个作业要求在哪里 | 结对项目 |
这个作业的目标 | 合作完成一个自动生成小学四则运算题目的命令行程序 |
结对组合成员介绍
结对组合成员姓名 | 学号 | GitHub项目地址 |
---|---|---|
苏清仪 | 3222004337 | GitHub项目地址 |
张易欣 | 3222004811 | GitHub项目地址 |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
Estimate | 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 480 | 480 |
Analysis | 需求分析 (包括学习新技术) | 80 | 100 |
Design Spec | 生成设计文档 | 30 | 10 |
Design Review | 设计复审 | 20 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
Design | 具体设计 | 60 | 60 |
Coding | 具体编码 | 100 | 100 |
Code Review | 代码复审 | 30 | 120 |
Test | 测试(自我测试,修改代码,提交修改) | 80 | 300 |
Reporting | 报告 | 50 | 60 |
Test Repor | 测试报告 | 20 | 20 |
Size Measurement | 计算工作量 | 20 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 10 | 20 |
合计 | 1040 | 1130 |
开发环境
- 开发语言:Java
- 编译器:IDEA 2022.1
设计实现过程
生成题目和答案
- 首先根据输入-r和-n生成题目
- 将题目转换成String格式输入到题目集合
- 计算题目生成答案
- 将题目和答案分别写入文件
判定答案中的对错并进行数量统计
1.读取题目和答案文件
2.读取题目,并计算该题目答案
3.判断计算答案是否与文件答案相同,并放入对应结果集合
4.将结果写入文件
代码说明
Number类说明
包括fro(整数部分)、up(分数分子)、down(分数分母),方法包括加法、减法、乘法、除法、寻找最大公约数方法、分数格式转换、输出格式与分数转换、输入格式转换、分数值的计算
生成题目说明
/**
* 生成随机题目
* @param rand
* @return
*/
private static String generateRandomExpression(Random rand,int i) {
//符号范围是1-3
int opeNum= rand.nextInt(3)+1;
//生成具体表达式和格式
String res=formExpression(range,opeNum);
//生成格式
String result = res +"\n";
return result;
}
/**
* 具体的生成器
*/
private static String formExpression(int r,int opeNum){
Random random = new Random();
Number[] numList = new Number[opeNum+1];
String[] numListString = new String[opeNum+1];
String[] opeList = new String[opeNum];
StringBuffer str = new StringBuffer();
//随机生成符号
for(int i=0;i<opeNum;i++) {
opeList[i]=OPERATORS[random.nextInt(4)];
}
//先生成一个数值
Number number0 = built(r, random);
numList[0]=number0;
//随机生成数值
for(int i=0;i<opeNum;i++){
//减号
if(opeList[i]==OPERATORS[1]){
//比前面一个数字小
Number number=built(r,random);
while(!number.judge(numList[i],number)){
number=built(r,random);
}
numList[i+1]=number;
}else{
Number number=built(r,random);
numList[i+1]=number;
}
}
//转换为Sring格式
for(int i=0;i<=opeNum;i++){
numListString[i]=numList[i].toString(numList[i]);
}
//输出式子
for(int i=0;i<2*opeNum+1;i++) {
if(i%2==0) {
str.append(numListString[i/2]+" ");
}
if(i%2!=0) {
str.append(opeList[(i-1)/2]+" ");
}
}
str.append("="+" ");
return str.toString();
}
先生成符号的个数,最多不超过3个;根据-r的限制条件调用generateRandomExpression函数随机生成题目,当为减法时,保证前一个数字大于后一个数字,其中调用了formExpression函数具体题目生成器;再转换为Sring格式,输出式子到List中
生成答案说明
/**
* 生成答案
*/
public static String evaluateExpression(String expression) {
// 输入式子格式转换
String[] tokens = expression.split(" ");
List<String> list = new ArrayList<String>();
for (int i=0;i<tokens.length;i++){
list.add(tokens[i]);
}
// 变化为后缀表达式
List<String> list1 = simpleTosuffix(list);
// 后缀表达式计算
Number number = count(list1);
return number.toString(number);
}
/**
* 一般计算式转换为后缀表达式
* @param list
* @return
*/
public static List<String> simpleTosuffix(List<String> list){
List<String> Postfixlist = new ArrayList<String>();//存放后缀表达式
Stack<String> stack = new Stack<String>();//暂存操作符
for(int i=0;i<list.size();i++){
String s = list.get(i);
if(s.equals("=")||s.equals("\n")){
continue;
}
else if(s.equals("(")){
stack.push(s);
}else if(s.equals(OPERATORS[2])||s.equals(OPERATORS[3])){
stack.push(s);
}else if(s.equals(OPERATORS[0])||s.equals(OPERATORS[1])){
if(!stack.empty()){
while(!(stack.peek().equals("("))){
Postfixlist.add(stack.pop());
if(stack.empty()){
break;
}
}
stack.push(s);
}else{
stack.push(s);
}
}else if(s.equals(")")){
while(!(stack.peek().equals("("))){
Postfixlist.add(stack.pop());
}
stack.pop();
}else{
Postfixlist.add(s);
}
}
while(!stack.empty()){
Postfixlist.add(stack.pop());
}
System.out.println(Postfixlist);
return Postfixlist;
}
/**
* 后缀表达式计算
*/
public static Number count(List<String> list){
Stack<Number> stack = new Stack<>();
for(int i=0;i<list.size();i++){
String s = list.get(i);
if(!isOp(s)){
Number number=Number.ToNumber(s);
stack.push(number);
}else{
if(s.equals(OPERATORS[0])){
Number a1 = stack.pop();
Number a2 = stack.pop();
Number v = a2.add(a1,a2);
stack.push(v);
}else if(s.equals(OPERATORS[1])){
Number a1 = stack.pop();
Number a2 = stack.pop();
Number v = a2.sub(a2,a1);
stack.push(v);
}else if(s.equals(OPERATORS[2])){
Number a1 = stack.pop();
Number a2 = stack.pop();
Number v = a2.mut(a1,a2);
stack.push(v);
}else if(s.equals(OPERATORS[3])){
Number a1 = stack.pop();
Number a2 = stack.pop();
Number v = a2.div(a2,a1);
stack.push(v);
}
}
}
return stack.pop();
}
先将输入题目式子进行格式转换为List
测试运行
生成题目
生成答案
输入的题目和答案
输出判断结果
项目小结
在参与软件工程项目的过程中,我深刻体会到合作的重要性。项目开始时,我们首先进行了详细的需求分析,这帮助我们明确了目标和分工。通过每周的会议,大家分享各自的进展和遇到的问题,确保信息的透明和及时反馈。在编写代码时,我们根据各自的优势分配任务,提高了工作效率。此外,代码审查环节让我学到了很多,同学提出的建议让我意识到自己在某些地方的不足,帮助我不断改进。项目中还经历了一些挑战,比如技术难点和时间管理问题。我们通过讨论和集思广益,找到了有效的解决方案。通过这个项目,我认识到良好的沟通和相互支持是成功的关键。无这个经验让我更加期待未来的团队合作,希望能在今后的学习和工作中继续运用这些宝贵的经验。