java大作业pta4-6次大作业

一、前言

第四次大作业:

本次迭代在第三次大作业得基础上在题目类里增加了多选题和填空题,对于多选题得输入:格式:"#Z:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案 且标准答案中,如果包含多个正确答案,则正确答案之间用英文空格分隔,多选题得输出格式与一般答卷题目的输出一致,判断结果除了true、false,增加一项”partially correct”表示部分正确。计算总分答案包含所有正确答案且不含错误答案给满分;包含一个错误答案或完全没有答案给0分;包含部分正确答案且不含错误答案给一半分,如果一半分值为小数,按截尾规则只保留整数部分。填空题输入:"#K:"+题目编号+" "+"#Q:"+题目内容+" "#A:"+标准答案  其给分标准和多选题差不多。

知识涉及多态继承。

难度:难

第五次大作业

本次大作业需要模拟家居强电电路,主要有电路设备、受控设备、被控设备。本次大作业只有串联电路,且不考虑输入电压或电压差超过220V的情况。所以所有测试用例的所有连接信息都只包含两个引脚,除了开关可能出现多个,其他电路设备均只出现一次。电源VCC一定是第一个连接的第一项,接地GND一定是最后一个连接的后一项。

知识涉及类的设计、继承、多态,电路基础知识。

难度:难

第六次大作业

本次大作业基于第五次大作业的二次迭代,添加的内容为电路可能为并联、并且加了落地扇元件。本次迭代考虑电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落地扇的电阻为 20。本题中的并联信息所包含的串联电路的信息都在并联信息之前输入,不考虑乱序输入的情况。电路中的短路如果不会在电路中产生无穷大的电流烧坏电路,都是合理情况,在本题测试点的考虑范围之内。

知识涉及类的设计、继承、多态、重载、覆盖,电路基础知识

难度:难

二、设计与分析

第四次大作业:

对于第四次大作业,做了以下类图:

 

main类:主要是将处理后的数据按照对应规则输出。

dealstring类:主要是所有数据的输入、分类、存储、计算等。

students类:存储学生学号、姓名以及所答的试卷号

paper类:存储试卷号、总分等信息,将试卷号和试卷类用哈希map连接起来。

question类:有三个子类分别为普通题、多选题、填空题,存储结构上没有特别的区别,主要存储题号、内容以及题目是否被删。

 

程序流程:

首先进入主函数,跳转到dealstring类中处理字符串,用正则表达式将题目、试卷、学生、删除、学生考卷等信息分别传送到不同处理函数中。

如果是题目信息则分为三类,一个是普通题,一个是选择题,还有一个是填空题,函数dealque是将多余的字符截去,剩下的将其加入题目类存储。

如果是试卷信息,函数dealpaper定义一个哈希map存储顺序号和题号的关系,截去多余字符,然后将这张试卷加入一个哈希map存储对应试卷号和试卷类,并且返回这个试卷类

如果是学生信息,函数dealstu将信息存储在学生类中,然后定义一个哈希map存储学号和学生类的关系。

如果是删除信息,函数dealdelete则在题目sur(初始化为false)设为true,表示存在但已被删。

如果格式错误,则输出格式错误提示信息。

回到主函数,首先先将收集到的学生答卷答案信息传入ans类中进行排序:

public static Comparator<ans> compareNum = new Comparator<ans>() {
        @Override
        public int compare(ans a1, ans a2) {
            int comp = a1.getComplete().compareTo(a2.getComplete());
            if (comp == 0) {
                return Integer.compare(a1.getNum(), a2.getNum());
            }
            return comp;
        }
    };

而后遍历所有试卷,函数judgehun判断如果试卷满分没有达到100分,则输出未达到100分的提示信息。

开始对学生考卷进行遍历,函数judgepasur查找这张考卷的卷号是否有空白卷相应的卷号,如果没有找到,则输出试卷不存在的提示,没找到就continue继续浏览下一张试卷。接着函数judgestu判断这张答卷的学生是否存在,存在则通过学生学号找到相关学生的类,找不到则做一个标记flag。然后定义一个sum存储总分,开始顺序遍历这张卷子的题,先函数judgestuwrite判断学生是否写了这道题,如果没有则输出相关提示并且将这道题学生得分赋值为0,写了就判断这道题是否有被删除,被删除就输出相关提示,而后对比学生答案和标准答案判断学生是否写的正确,这里需要分为三个类型的题目的判断,如果是普通题,则只需要对比答案是否和学生答案一样;如果是多选题和填空题,则判断是否一样,不一样就判断学生答案在标答里是否存在相关字符,存在则得部分分:

public int judgezright(String str1,String str2){//第一个为标答,第二个为学生答案
        if(Objects.equals(str1 , str2)){
            System.out.println("true");
            return 1;
        }
        else if(check(str1,str2)){
            System.out.println("partially correct");
            return 2;
        }
        else{
            System.out.println("false");
            return 3;
        }
    }

最后如果学生存在则输出学生信息,如果不存在则输出找不到学生信息得提示。

第五次大作业

 

 Main类:主要输出已处理好的电路信息。

dealstring类:将电路分为两类,一类是串联电路各元件的信息,另一个是改变控制元件的状态信息,利用正则表达式将元件分类存储。

elec类:一共有六个子类,分别存储电路中所有的元件信息,计算元件输出值。

 

程序流程:

首先进入dealstring类中,如果是存储电路,则将输入的字符串传入处理电路连接connect函数中,将有用信息提取后传入add函数,函数中用正则表达式区分各种元件,new一个相关元件的类,将基本信息存储后加入到总电路circuit数组中。如果是改变受控元件的状态的字符串,则将字符串传入change函数中按照字符串所要求进行改变元件状态。处理后对电路中的元件进行排序:

public void sortStrings(ArrayList <String> list) {
        // 自定义优先级顺序
        String priorityOrder = "KFLBRD";
        Collections.sort(list, new Comparator <String>() {
            @Override
            public int compare(String s1, String s2) {// 取首字符
                char c1 = s1.charAt(0);
                char c2 = s2.charAt(0);// 首字符优先级比较
                int index1 = priorityOrder.indexOf(c1);
                int index2 = priorityOrder.indexOf(c2);
                if (index1 != index2) {
                    return Integer.compare(index1, index2);
                }// 如果首字符优先级相同,则比较数字部分
                int num1 = Integer.parseInt(s1.substring(1));
                int num2 = Integer.parseInt(s2.substring(1));
                return Integer.compare(num1, num2);
            }
        });
    }

之后回到主函数,传入check函数计算电位值,最后只需要按照顺序将各个元件输出。

以下为本次顺序图:

 

第六次大作业

Main类:主要是输出处理后的电路信息。

dealstring类:处理字符串的输入、分类、计算、排序、存储等,包括将整个电路元件存储,线路存储,并联存储等。

elec类:主要有八个子类,除了上次的六种,本次迭代更新了并联子类和落地扇子类。将并联看成一个元件进行计算。

thread类:线路类,存储字符串以T开头的一整条串联线路并计算这条线路的总电阻和总电压。

 

程序流程:

首先进入dealstring处理字符串,跟上次对比,这次输入大致分为三类,一类是以T开头的线路输入,一类是以M开头的并联输入,一类是改变各种电器状态。

这是dealstring的存储信息:

    ArrayList<String> circuit = new ArrayList<>();//存储所有元器件
    ArrayList<String> way = new ArrayList <>();
    HashMap find = new HashMap<String,elec>();
    HashMap<String,thread> thfind = new HashMap <>();//线路存储
    HashMap<String,parconnect> parfind = new HashMap <>();//并联存储

第一类传入connect函数,判断是分线路还是总线路,如果是分线路则传入addthread函数,将这一条所有元件存储后加入thread类中,如果是总线路则传入add函数,将所有元件存储在电路图circuit中,其中并联元件将存储在parfind中,所有线路将存储在thfind中,并联类parconnect中有存储结构parcircuit,专门存储这个并联所有的线路。

计算并联电阻需要计算各个线路的电阻,计算线路电阻:

        for(String temp : this.scircuit){
            if(Pattern.compile("D\\d+").matcher(temp).matches()){//吊扇
                R += 20;
            }
            else if(Pattern.compile("R\\d+").matcher(temp).matches()){//日光灯
                R += 5;
            }
            else if(Pattern.compile("B\\d+").matcher(temp).matches()){//白炽灯
                R += 10;
            }
            else if(Pattern.compile("A\\d+").matcher(temp).matches()){//落地扇
                R += 20;
            }
        }

将所有字符串预处理完后返回主函数计算电压值,首先函数先判断该线路是否开路,其中要注意并联中两个开关都开的情况。之后check函数计算电压,根据题目给的电阻,先计算电路的总电阻,这个在将元件加入电路中时已有预处理,然后再计算该电路的总电压,之后通过总电压和总电阻计算出总电流,而后分别遍历每一个元件利用电流计算每个元件的电压。最后回到主函数输出所有元件的信息。

 

三、踩坑心得

首先对于第四次大作业,这个题目已经经历了3次迭代,所以一些代码我没有写注释,大概子知道什么意思就直接拿来用了,然后之前没有考虑到的情况都在迭代后的题目版本中暴露了代码弊端,然后也因为没写注释,很多代码同一功能但我写了很多同种类功能的函数,都是为了对之前的代码漏洞修修补补,代码复用性已经很不高了。

然后是第五次大作业,觉得大物已经离我很远了)这次代码还挺顺利就写出来了,一开始只拿了68分,以为是精度问题,结果和同学对拍的时候发现我没认真看题目,输出需要按照一定顺序,我没有排序,排完序后就满分了。

最后是第六次大作业,这次问题主要出现在计算并联电阻上,我一开始的代码的并联电阻只支持计算2个线路并联的情况,3个线路就会出错,而题目中应该是有3个线路并联的电路。然后修改后计算每个元件的电压,我一开始是觉得并联的电压都以牙膏,所以就直接用并联元件的电压表示并联内各个元件的电压,后来发现,并联里面还可能有串联,还需要分压。

 

四、改进建议

我一般会边看一遍题目然后看着样例写代码,这样的话我比较容易知道自己下一步该写什么,但是这很容易忽视掉题目中的细节比如第五次作业中的排序,以后写代码还是边看题目边写一个块的代码。

接着就是注释问题,有点懒,有些不想注释完整,导致后面看到自己的注释只有两个字怎么想也想不起来这两个字的含义是什么,然后就会以为自己没有写这个功能的代码然后又写了一遍或者在类里面多次定义,比如第四次作业中,判断卷子是否满分,我的试卷类中又一个hun变量int类型计算这张卷子是分数,还有一个have是boolean类型是判断这张卷子是否满分,have是我第二次迭代写的,而这次迭代我就以为have是卷子是否存在的意思。

最后就是考虑问题的完整性,第六次作业还是和同学对拍的时候才意识到可能出现三条线路的并联,并联中可能还有串联这些情况,(本来打算就这样算了的,结果找到错误了。

写代码之前多在纸上模拟情况吧,如果只是看着代码真的想不出还有什么情况。

 

五、总结

这几次写大作业的时间明显会比前三次快很多,我记得我第二次大作业搓代码从下午两点一直搓到晚上十二点才基本成型,这次差不多一个晚上能成型,然后之后对拍修修补补也差不多一个下午时间。通过这几次大作业,继承、多态、抽象接口这几个知识点都在实践中得到了很好的理解,但是自己还是忘性比较大,写完后面代码就把前面代码几乎都忘光了,后面代码引用前面写的类基本上就是凭感觉+注释,其实即使我写了注释我也要想一段时间,可能注释不够具体?之后注释具体一点吧。

posted @ 2024-11-22 02:09  DLSQS  阅读(53)  评论(0)    收藏  举报