作业3
这个作业属于哪个课程 | <班级的链接> |
---|---|
这个作业要求在哪里 | <作业要求的链接> |
这个作业的目标 | 学会合作完成一个项目,完成一个四则运算的程序 |
项目成员 | 学号 |
---|---|
陈嘉灏 | 3122004561 |
李德炜 | 3122004574 |
Github:地址
2、PSP表格
Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|
计划 | 20 | 20 |
· 估计这个任务需要多少时间 | 20 | 20 |
开发 | 730 | 970 |
· 需求分析 (包括学习新技术) | 120 | 130 |
· 生成设计文档 | 10 | 20 |
· 设计复审 | 20 | 30 |
· 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· 具体设计 | 30 | 60 |
· 具体编码 | 420 | 500 |
· 代码复审 | 60 | 100 |
· 测试 | 60 | 120 |
报告 | 60 | 55 |
· 测试报告 | 30 | 30 |
· 计算工作量 | 10 | 10 |
· 事后总结, 并提出过程改进计划 | 20 | 15 |
合计 | 810 | 1045 |
3、效能分析
测试覆盖率:
4、设计实现过程
graph TB
A(Main)-->|输入参数|F{判断}
F-->|count>0且maxValue>0|B(repeat)-->C(generateExpress)-->D(InfixExpression.resultCal)
F-->|subjectPath!=null且answerPath!=null|E(checkAnswer.checkA)
5、代码说明
计算模块:
//采用类似入栈出栈的方法(此处用集合代替栈),将中缀表达式转换成后缀表达式然后进行计算
public static List<String> getSuffixExpressions(List<String> l)//将中缀表达式转换成后缀表达式后存到一个集合中并返回
{
List<String> list1= new ArrayList<>();//存放符号
List<String> list2= new ArrayList<>();//存放后缀表达式
for (String item : l){
if (!(item.equals("+")||item.equals("-")||item.equals("×")||item.equals("÷")||item.equals("(")||item.equals(")"))) {
list2.add(item);//识别是否为数字
}else if (item.equals("(")){
list1.add(item);
}else if(item.equals(")")){
while(!list1.get(list1.size()-1).equals("(")&&!list1.isEmpty()){
list2.add(list1.get(list1.size()-1));
list1.remove(list1.size()-1);
}
list1.remove(list1.size()-1);
}else {
while (!list1.isEmpty()&&Operation.getValue(list1.get(list1.size()-1))>=Operation.getValue(item)){
//判断是否栈空或者优先级够不够
list2.add(list1.get(list1.size()-1));
list1.remove(list1.size()-1);
}
list1.add(item);
}
}
while (!list1.isEmpty()){
list2.add(list1.get(list1.size()-1));
list1.remove(list1.size()-1);
}
return list2;
}
public static String resultCal(List<String> list){
List<String> list3 = new ArrayList<>();//存放数字
for (String ele : list){
if (!(ele.equals("+")||ele.equals("-")||ele.equals("×")||ele.equals("÷"))){
list3.add(ele);//不是符号则入栈
}else {
String num2=list3.get(list3.size()-1);list3.remove(list3.size()-1);//取尾元素并删除,即出栈
String num1=list3.get(list3.size()-1);list3.remove(list3.size()-1);
String res;//存放两数运算的结果
res=calculate.numberCalculate(num1,num2,ele);
if(res==null){
return null;//出现负数则返回null
}
list3.add(res);
}
}
return list3.get(list3.size()-1);
}
static class Operation{
public static int getValue(String ess){
int res= 0;//为符号添加优先权值
switch (ess){
case "+", "-":
res=1;
break;
case "×", "÷":
res=2;
break;
default:
break;
}
return res;
}
}
生成数字:
public static String fractionGenerate(int max) {
//生成分数,包含真分数
Random ran = new Random();
int num=ran.nextInt(max);
int den=ran.nextInt(max);
while (den==0){den=ran.nextInt(max);}
while (num==0){num=ran.nextInt(max);}
return calculate.Simplify(num, den);
}
public static String numberGenerate(int max) {
//生成整数
Random ran = new Random();
return String.valueOf(ran.nextInt(max));
}
计算答案准确:
public static void checkA(String exeFile,String answerFile,String gradeFile){
File file1 = FileUtil.file(exeFile);//表达式文件
File file2 = FileUtil.file(answerFile);//答案文件
if (!file1.exists() || !file2.exists())
{
System.out.println("输入的文件不存在");//文件不存在就报错
return;
}
List<String> expression = FileUtil.readLines(file1, "UTF-8");//读取
List<String> answer = FileUtil.readLines(file2, "UTF-8");
Queue<Integer> correctAnswer = new LinkedList<>();//正确题目的队列
Queue<Integer> wrongAnswer = new LinkedList<>();//错误题目的队列
for (int j=0;j<expression.size();j++) {
String[] temp;
temp = expression.get(j).split(" ");//去除空格
List<String> infix = new ArrayList<>();
Collections.addAll(infix, temp);
infix.remove(0);//去除题号
StringBuilder infixTemp = new StringBuilder();
for (String s : infix) {
infixTemp.append(s);
}//将集合转换为字符串
List<String> infix2 = checkAnswer.getInfixExpression(infixTemp.toString());//将连在数字旁的括号拆开并存到集合中
String result =InfixExpression.resultCal(InfixExpression.getSuffixExpressions(infix2));//计算结果
if (Objects.equals(result, answer.get(j))){
correctAnswer.add(j+1);//答案一致则将题号加入队列
}else {
wrongAnswer.add(j+1);
}
}
File grade = FileUtil.file(gradeFile);//判断对错文件
String cor="";
String wro="";
cor +="correct: "+correctAnswer.size()+correctAnswer+"\n";//按要求中的格式
wro +="wrong: "+wrongAnswer.size()+wrongAnswer+"\n";
FileUtil.appendUtf8String(cor,grade);//存入对应文档
FileUtil.appendUtf8String(wro,grade);
System.out.println("correct: "+correctAnswer.size()+correctAnswer);//打印结果
System.out.println("wrong: "+wrongAnswer.size()+wrongAnswer);
}
算法参考:中缀表达式转换成后缀表达式
6、测试运行
测试生成10000道题:
测试对比答案功能:(为了测试手动将答案文件最后五题的答案改成错误的)
exe测试:
7、项目总结
1、使用新方式:第一次通过使用git进行合作,方便操作
2、在项目完成的过程中,经过交流和学习,提高了编程的水平
3.不足之处:未完成不生成重复表达式的功能,还有一些功能可以优化