作业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.不足之处:未完成不生成重复表达式的功能,还有一些功能可以优化

posted @ 2024-03-24 15:01  星陨2333  阅读(61)  评论(0编辑  收藏  举报