首页 > 其他分享 >结对项目

结对项目

时间:2024-03-25 22:45:02浏览次数:26  
标签:结对 return String 项目 List rightE null 表达式

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024
这个给作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024/homework/13137
这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序

合作人员

姓名 学号
黄冬炫 3122004570
盘伟铖 3122004579

一、github链接:https://github.com/sunwu12/project2.git

二、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 25
-Estimate -估计这个任务需要多少时间 20 20
Development 开发 785 847
-Analysis -需求分析 (包括学习新技术) 300 280
-Design Spec -生成设计文档 20 20
-Design Review -设计复审 20 22
-Coding Standard -代码规范 (为目前的开发制定合适的规范) 5 5
-Design -具体设计 150 180
-Coding -具体编码 220 260
-Code Review -代码复审 40 45
-Test -测试(自我测试,修改代码,提交修改) 30 35
Reporting 报告 43 55
-Test Repor -测试报告 15 20
-Size Measurement -计算工作量 10 15
-Postmortem & Process Improvement Plan -事后总结, 并提出过程改进计划 18 20
All 合计 848 927

三、效能分析

四、设计实现过程

类:

  1. Expression:表达式对象类,包含表达式字符串、表达式的值、表达式的主运算符等属性,用于构造复杂的且带有括号的表达式
    • splicing:拼接表达式。将两个表达式对象拼接成一个新的表达式对象。
    • addBrackets:生成括号。为表达式添加括号
    • getRandomValue:生成随机数。生成没有运算符的一个随机表达式对象
  2. Fraction:(真)分数对象类,包含分子、分母、分数数值等属性,用于构造一个可自动约分、化简的真分数
    • fractionCalculate:分数计算。计算两个分数的运算结果
    • transformValue:分数转换。根据输入的分子分母转换成Fraction对象
    • fractionSimplify:分数化简。化简约分分数对象
  3. ExpGeneration:表达式生成类,生成随机表达式
    • getExpression:生成一个随机的表达式(0<运算符个数<=3)
    • getAllExpression:生成指定数量的表达式集合
  4. ExpHandle:表达式处理类
    • calExpressionString:表达式计算。根据表达式字符串计算表达式的值
    • getInfixExpression:将表达式字符串转成中缀表达式
    • getPostfixExpression:将中缀表达式转换成后缀表达式
    • getSignPriority:获取运算符的优先级
    • handleList:将后缀表达式中的两个数值与一个运算符进行合并运算
    • checkDuplicate:判断两个表达式字符串是否重复,借助字符串的后缀表达式进行判断
  5. TxtHandle:文件操作类
    • txtRecord:将生成的随机表达式集合存入到题目文件和答案文件中
    • txtJudge:对题目文件和答案文件中的每一行题目和答案进行结果比对,并将结果写入Grade.txt文件中

五、代码说明

  1. 表达式拼接

    //拼接两个表达式成一个
    public static Expression splicing(Expression leftE,Expression rightE,char sign){
        if(leftE==null||rightE==null)return null;
        int newNum=leftE.num+rightE.num+1;
        Expression newE=new Expression();
        //运算符个数超过3个
        if(newNum> newE.maxNum)return null;
        if((newE.value=Fraction.fractionCalculate(leftE.value,rightE.value,sign))==null)return null;
        //添加括号
        if(sign=='×'||sign=='÷'){
            if(leftE.keySign=='+'||leftE.keySign=='-')addBrackets(leftE);
            if(rightE.keySign=='+'||rightE.keySign=='-')addBrackets(rightE);
        }
        if(sign=='÷'&&(rightE.keySign=='÷'||rightE.keySign=='×'))addBrackets(rightE);
        if(sign=='-'&&(rightE.keySign=='+'||rightE.keySign=='-'))addBrackets(rightE);
        newE.keySign=sign;
        newE.num=newNum;
        newE.expression=leftE.expression+' '+sign+' '+rightE.expression;
        return newE;
    }
    

    将两个表达式和一个运算符拼接成一个新的表达式,过程中会计算两个表达式的运算结果存入到新表达式的value中,并根据左右表达式的运算符添加括号

  2. 判断表达式是否重复

    public static Boolean checkDuplicate(String expression1, String expression2) {
        List<String> e1 = getPostfixExpression(expression1);
        List<String> e2 = getPostfixExpression(expression2);
        if (e1.size() != e2.size()) return false;
        if (!Objects.equals(calExpressionString(expression1), calExpressionString(expression2))) return false;
        String[] sinList1 = new String[2];
        String[] sinList2 = new String[2];
        do {
            e1 = handleList(e1, sinList1);
            e2 = handleList(e2, sinList2);
            if (!Arrays.equals(sinList1, sinList2)) return false;
            if (e1 == null || e2 == null) {
                break;
            }
        } while (e1.size() != 1);
        return true;
    }
    
    private static List<String> handleList(List<String> list, String[] sinList) {
            int i = 0;
            Pattern pattern = Pattern.compile("[+×÷-]");
            //每进行一次,去除一个运算符,合并两个数值
            while (i < list.size()) {
                String str = list.get(i);
                Matcher matcher = pattern.matcher(str);
                if (matcher.find()) {
                    char sign = str.charAt(0);
                    List<String> newList = new ArrayList<>(list);
                    String newVal = Fraction.fractionCalculate(newList.get(i - 2), newList.get(i - 1), sign);
                    if (newVal == null) return null;
                    sinList[0] = newList.get(i - 2);
                    sinList[1] = newList.get(i - 1);
                    Arrays.sort(sinList);
                    newList.set(i - 2, newVal);
                    newList.remove(i - 1);
                    newList.remove(i - 1);
                    return newList;
                }
                i++;
            }
            return null;
        }
        
      @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass()!= o.getClass()) return false;
            Expression exp = (Expression) o;
            return ExpHandle.checkDuplicate(this.expression,exp.expression);
        }
    

    先将两个表达式字符串都转成后缀表达式数组,再多次调用handleList方法将后缀表达式中的两个数值和一个运算符合成一个结果数值,其中sinList是由每次计算的两个值组合的数组,如果每次调用得到两个表达式的sinList有一次不相同,则视为两表达式不重复。最后重写Expression的equals方法,即可实现生成的随机表达式集合中没有重复的表达式

  3. 判断表达式结果对错



public static void txtJudge(String subjectPath,String answerPath) {
        List<String> subjectList=FileUtil.readUtf8Lines(subjectPath);
        List<String> anwerList=FileUtil.readUtf8Lines(answerPath);
        //将读取的表达式中的等于号去掉
        List<String> expList=subjectList.stream().map(s->s.replace(" =","")
                .split("^\\d+\\.")[1]).toList();
        List<String> valList=anwerList.stream().map(s->s.replace(" =","")
                .split("^\\d+\\.")[1].trim()).toList();
        int[] gradeList=new int[subjectList.size()];
        for(int i=0;i<subjectList.size();i++){
            //计算正确则为1,反之为0
            gradeList[i]= Objects.equals(ExpHandle.calExpressionString(expList.get(i)), valList.get(i)) ?1:0;
        }
        StringBuilder sb1=new StringBuilder();
        StringBuilder sb2=new StringBuilder();
        //根据1,0的个数判断题目正确个数
        long corNum=Arrays.stream(gradeList).filter(i->i==1).count();
        long wroNum=Arrays.stream(gradeList).filter(i->i==0).count();
        sb1.append("Correct: ").append(corNum).append("(");
        sb2.append("Wrong: ").append(wroNum).append("(");
        for(int i=0;i<subjectList.size();i++){
            if(gradeList[i]==1) {
                sb1.append(i + 1).append(",");
            }
            else sb2.append(i+1).append(",");
        }
        if(sb1.charAt(sb1.length()-1)==',')sb1.deleteCharAt(sb1.length()-1);
        if(sb2.charAt(sb2.length()-1)==',')sb2.deleteCharAt(sb2.length()-1);
        sb1.append(")");
        sb2.append(")");
        FileUtil.writeUtf8Lines(new ArrayList<>(List.of(new String[]{sb1.toString(),sb2.toString()})), GRADE);
    }

先读取题目文件中的表达式集合,并去除等于号,再根据calExpressionString方法逐条计算表达式字符串的结果是否与答案文件中的结果相同,相同记为1,不相同记为0;接着根据1,0数量计算题目的正确、错误个数并写入到grade.txt文件中

六、测试运行

@Test
public void testMain(){
    //获取随机表达式集合
    List<Expression> es= ExpGeneration.getAllExpression(30,20);
    for(Expression e : es){
        System.out.println(e);
    }
    //将表达式集合写入题目文件和答案文件中
    TxtHandle.txtRecord(es);
    //测试文件正确表达式个数
    try {
        TxtHandle.txtJudge("src/resources/Exercises.txt",
                "src/resources/Answers.txt");
    }catch (Exception e){
        System.out.println("文件格式不正确");
    }

}

其中2、5、8、15条数据人为修改过答案,故出现4个错误数

同时该项目可生成10000+不重复的表达式

七、项目小结

关于设计:原本是想着用后缀表达式来实现生成随机的表达式,但是过程中发现这样子不好生成括号,于是专门写了一个对象类用于实现生成带括号的表达式。
关于查重,因为是用对象来实现表达式,所以重写了对象的equals方法来实现判断俩个表达式是否重复,以确保生成的随机表达式当中不会出现重复的。
关于结对合作:在该结对项目中,我们学习了如何高效沟通,共同分析项目中的算法

标签:结对,return,String,项目,List,rightE,null,表达式
From: https://www.cnblogs.com/130L/p/18095202

相关文章

  • 海量数据处理项目-阿里编码规范里面Manager分层介绍和开发规范说明
    ......
  • 读取的项目数必需是列数的倍数
     001、R语言出现如下报错:读取的项目数必需是列数的倍数>egg<-read.table("XXX.emapper_reformat.annotations",sep="\t",header=T)Warningmessages:1:Inscan(file=file,what=what,sep=sep,quote=quote,dec=dec,:EOFwithinquotedstring......
  • 结对项目
    结对项目作业所属班级https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024作业的要求https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024/homework/13137我理解的作业目标完成四则运算的算法完成以及软件开发到应用的实现本项目由郭亮(学......
  • 结对项目
    |这个作业属于哪个课程|软件工程||-----------------|---------------||这个作业要求在哪里|结对项目||这个作业的目标|完成四则运算生成,熟悉结对流程|结对成员陆靖3122004621陈家谦3122004602GitHub链接仓库psp表格PSP2.1PersonalSoftwareProc......
  • 结对项目
    这个作业属于哪个课程https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024/这个作业要求在哪里https://edu.cnblogs.com/campus/gdgy/SoftwareEngineering2024/homework/13137这个作业的目标通过合作完成一个四则运算项目来了解项目开发流程项目合作......
  • Flink API的四层抽象级别是什么?能用实际项目案例讲解一下吗? Flink API的四层抽象级别
    FlinkAPI的四层抽象级别是什么?能用实际项目案例讲解一下吗?首先,FlinkAPI的四层抽象级别是指:最底层抽象:ProcessFunctionAPI、核心API:DataStreamAPI、TableAPI、SQL。这四个抽象级别可以比作烹饪中的不同方式,从简单的速食制作到复杂的大餐烹饪。1.最底层抽象:ProcessFunctionAP......
  • 【旅游景点项目日记 | 第二篇】基于Selenium爬取携程网景点详细数据
    文章目录3.基于Selenium爬取携程网景点详细数据3.1前提环境3.2思路3.3代码详讲3.3.1查询指定城市的所有景点3.3.2获取详细景点的访问路径3.3.3获取景点的详细信息3.4数据库设计3.5全部代码3.6效果图3.基于Selenium爬取携程网景点详细数据3.1前提环境确保安装pytho......
  • SpringBoot3项目使用Knife4j时访问doc.html出现Knife4j文档请求异常且开发者工具网络
    1.在各个pom.xml中替换Knife4j的依赖版本,升级为4.0以上,如果找不到依赖可以在Maven配置中多添加几个镜像,或者使用汉化插件重启IDEA;<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId......
  • 在线试题答题考试系统项目开发搭建源码
    这是关于在线试题答题考试系统项目的程序开发:PHP+MySQL程序演示:http://ks1.yetukeji.top,账户13112215717,密码qq2607788043程序开源:代码全部开源,支持任意二开功能介绍:多种试题类型支持判断题、单选题、多选题、填空题、简答题、材料题六种试题类型多种试题难度支持简单......
  • 结对项目
    作业所属班级软件工程2024作业要求自动生成四则运算作业目标实现论文查重姓名梁爽唐育健学号31220048723122004879该项目的GitHub仓库链接PSP表格PSP2.1PersonalSoftwareProcessStages预估耗时(分钟)实际耗时(分钟)Planning计划......