首页 > 编程语言 >JAVA-PTA题目集2总结

JAVA-PTA题目集2总结

时间:2024-11-22 17:07:32浏览次数:1  
标签:串联 题目 String PTA 电路 并联 更新 JAVA 设备

  1. 前言
            经过这几次JAVA练习题的训练,我对JAVA编程语言有了更深入的理解,同时在程序开发设计环节也有了很大的进步,吸收了上次编程练习的教训后,我在本阶段的编程练习中也有针对性的进行了改进。
            本次的JAVA练习内容丰富,包括各种数据结构的应用,如哈希表,列表,数组等;迭代器的使用;创建有序集合;类关系的应用,如继承关系以及抽象类和抽象函数的复写问题等。而主要难点在于这几次练习的逻辑设计和代码运行流程上。
            这次的三个JAVA练习难度上依旧是由浅入深,难的部分主要集中在答题判题程序和两次电路迭代程序,本次我主要针对这三个问题详细阐述我在编程中的设计和遇到的问题。

  2. 设计与分析
    2.1 答题判题程序
            在答题判题程序中,由于已经有了前几次的经验,只需要在先前的基础上对程序逻辑和运行进行修改和调试即可。本次判题程序新增的内容是对题目进行了改进,将题目分为选择题,多选题,填空题等。因此在判定的时候也有了更高的要求,多选题、填空题有新增部分正确的判定,同时,作答和标准答案的匹配也要更新,在分数计算上也要新增规则,部分正确得一半分;还要考虑多个同学有多张不同试卷的答卷的情况,需要按优先级进行排序输出。
    系统设计类图:
            在处理题目分类的时候,我采取的处理方法是将题目类抽象出来,提供通用的属性和方法供不同的题目类继承,这样做的好处是提供了一种模板机制,通过定义一些通用的行为和属性,而具体的实现则留给子类来完成。这样在不同题目继承抽象类后,他们的方法虽然不同,但是有一样的名字,不需要设计不同的名字引起歧义,同时也可以拥有自己的新增属性,从结构化的角度来说是有利于程序运行的。

        `abstract class Question{
             protected int questionNum; // 题号
             protected String question; // 题目内容
             public Question(int questionNum, String question);
             public int getQuestionNum();
             public String getQuestion();
             public abstract boolean isCorrect(String answer); // 判断答案是否正确的方法,子类实现
             public abstract int getScore(String answer, int fullScore); // 获取题目得分的方法,子类实现
         }`
    

其次,处理判题时的部分正确问题,由于作答答案和标准答案可能存在顺序上的不同,一开始我的设计是通过if结构判断,或者采用二级链表进行存储,但是这样无论是在代码量还是存储量上都很大,于是我在经过网上查找资料后,发现JAVA提供了contains()方法,这是Set接口中的一个方法,用于检查调用该方法的集合中是否包含指定的元素。如果包含,则返回true,如果不包含,则返回false。这样,判定题目正确/错误/部分正确的问题就解决了,得分问题也解决了。

          `public int getScore(String answer, int Score){
                  if(answer.trim().equals(standAnswer_Set))   return Score;
                  else if(standAnswer_Set.contains(answer.trim()) && !answer.trim().isEmpty()){
                      return Score / 2; //部分正确得一半分
                  }
                  return 0;
          }`

最后是优先级排序输出问题,要实现answerSheet集合中的Answer对象首先按照学生ID排序,然后在学生ID相同的情况下,按照试卷ID排序,而JAVA中正好也存在这样一个方法,可以实现我们需要的排序。Comparator.conparing()方法是Java中用于创建一个比较器(Comparator)的方法,该比较器根据提供的函数对对象进行比较,thenComparing()方法则是用来在第一个比较条件相同的情况下,提供第二个比较条件,从而实现优先级输出。
answerSheet.sort(Comparator.comparing(AnswerSheet::getStudentID).thenComparing(AnswerSheet::getPaperId));
2.2 家居强电电路模拟程序
2.2.1 模拟1
        在模拟1中涉及对整个电路的结构设计,在参考设计后,我设计了一个二级继承模型,抽象类设备CircuitDevice,抽象类受控设备和控制设备分别继承设备类,具体的开关、分档调速器、白炽灯等则继承控制设备和受控设备。此外,我还创建了一个Circuit类用来保存电路信息,这是系统设计类图:

顺序图如下:

        在模拟1中,主要存在这样几个要点:
        1. 计算电路中各元器件的电压,并对其状态进行更新
        这一部分的实现主要是通过updateDevices()函数完成的,在这个函数中主要有三个数据结构,分别存储设备、串联电路和各元器件电压。

      public Map<String, CircuitDevice> devices = new HashMap<>();//存储电路中的电路设备
      public List<String[]> connections = new ArrayList<>();//存储串联电路
      public Map<String, Double> voltages = new HashMap<>();

由于电路中可能存在的可以改变电压的控制元件,因此需要优先判断设备的归属问题,如果是开关,则讨论开关状态,闭合则继续,否则将VCC的输出改为0.0,由于所有设备默认都是未开启状态,因此不需要对后续设备继续维护,直接结束输出即可;如果是连续调速器或者分档调速器,则需要按照挡位对VCC的输出进行更新;如果只是普通元器件,如白炽灯等,则按照类中的方法更新设备状态。
        2. 注重串联电路的电路特点,关注元器件的先后顺序
        由于在约束条件中规定:对于调速器,其输入端只会直连VCC,不会接其他设备,且整个电路中最多只有一个调速器连接在电源上。因此只需要对剩余元器件进行判定,举个例子,在串联电路的末端有开关,且开关没有闭合,此时电路处于断路状态,不应该对设备进行更新,这种情况应该避免,因此需要关注元器件的先后顺序,如果toDevice是开关,则应该将inputVoltage置为0.0,然后对前面的设备重新进行更新。

        else if(toDevice instanceof Switch ){
            Switch sw = (Switch) toDevice;
            if (!sw.on) {
                inputVoltage = 0;
                fromDevice.updateState(inputVoltage);
            }
        }

3. 设备更新方法
        值得注意的是,由于输入格式和顺序问题,我们采用了fromDevice和toDevice来进行设备判定和更新,在判定完设备类别以后,以开关为例,可以利用强制类型转换新建一个开关,对这个新建的开关执行状态转换函数,而不是从列表中取出设备,然后对原有设备进行状态转换。这样操作同样可以达到维护设备列表的目的,而且易于书写,同时增加了代码的可读性。

    if(message.startsWith("#K")){
        String id = message.substring(1);
        Switch sw = (Switch) devices.get(id);
        if(sw != null)  sw.toggle();  //开关状态转换
    }

4. 按照规定的顺序进行输出
        对电路基本判定和设备信息进行修改后就可以进行输出了,本次输出需要按照规定的顺序对设备信息进行输出。一开始我的设计是为每种设备设计输出优先级的属性,在每个变量初始化时在构造函数中规定优先级,但是这样做在编译时常常产生错误,因为我最终放弃了这种方法。在经过资料查找后,我采用的方法是,先建立哈希表为不同设备建立优先级,然后重写sort()函数,实现按照题目规定的顺序进行输出。

    arr.sort(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            String prefix1 = o1.substring(0, 1);
            String prefix2 = o2.substring(0, 1);
            int order1 = orderMap.getOrDefault(prefix1, 0);
            int order2 = orderMap.getOrDefault(prefix2, 0);
            if (order1 != order2) {
                return Integer.compare(order1, order2);
            } else {
                return o1.compareTo(o2);
            }
        }
    });

2.2.2 模拟2
        在模拟2中,电路中会出现并联电路,同时新增了一种设备,最大的变化是,受控设备新增电阻属性。在总体结构上,新增的落地扇类只需要继承受控设备类即可,而并联电路则需要在Circuit类中新增一个哈希表来进行存储,但是由于并联电路是由串联电路组成,因此存储时将串联电路id存入,最后从串联电路的哈希表中取出即可。
        在模拟2中主要存在这样几个要点:
        1. 判断串联电路和并联电路的状态
        串联电路存在三种状态:有电阻联通(正常),无电阻联通(短路)和断路。并联电路也存在三种状态:被支路短路,支路均联通(正常),所有支路全断(断路)。由于状态都有三种,因此在判断状态函数中不宜用boolean作为返回值类型,而是采用了int。
        判断串联电路:如果所有控制元器件都正常(开关闭合,调速器挡位不为0),并且串联电路电阻不为0,那么串联电路为正常;如果有控制元件断开,串联电路断路;如果所有控制元器件正常,但串联电路电阻为0,串联电路短路。
        判断并联电路:由于并联电路是由串联电路组成的,只需要循环遍历所有串联电路再判断并联电路状态即可。如果所有支路均为断路,则并联电路断路;如果存在支路短路,则并联电路短路;否则并联电路正常。
        2. 计算串联电路和并联电路的电阻
        在计算电阻时会利用电路状态,这样在后续电路设备更新的时候可以得到便利。
        串联电路:如果串联电路无电阻联通,返回0.0;如果断路,返回double类型的最大值Double.MAX_VALUE;如果有电阻联通,返回所有元器件的电阻值的和即可。
        并联电路:并联电路断路,返回double类型的最大值Double.MAX_VALUE;并联电路短路,返回0.0;并联电路正常,利用并联电路的电阻计算公式进行计算即可,无需在意存在支路断路,若支路断路,利用double类型最大值进行计算对结果产生的误差很小。
        3. 电路设备状态更新
        由于本次迭代考虑电阻,因此我们需要选择电压或者电流进行辅助计算。我选择的是电流。
        首先判断总干路状态(利用串联电路状态判断函数),如果状态正常(有电阻联通),才继续更新设备状态,否则直接结束输出即可。
        然后对VCC的输出电压进行更新,VCC后如果连了调速器,则应该根据调速器挡位进行电压的更新。这一步进行完后就可以得出干路总电流。
        随后就可以开始逐个对设备进行更新,控制设备与模拟1的更新相同,在受控设备更新时,需要注意的是用压降作为传参的依据,由于模拟1中不考虑电阻,因此直接用前端设备的输出电压进行更新即可,而本次更新则需要用压降作为传参的依据。同时,在设备更新完之后,需要对volt进行更新,因为产生了压降,因此后端设备的输入电压必须更新才能存放。
        如果再遍历干路设备时遇到了并联电路,那么将压降进行传参对并联电路进行更新,并联电路的更新只需要遍历每一条支路,用压降对支路设备进行设备更新即可(这个地方可以参考模拟1中的更新)。由于有并联电路的电阻计算函数,对其进行压降计算也是很方便的。
3. 练习心得
3.1 数据问题
        在几次输出时,总是遇到样例结果与输出结果有一点偏差的结果,是因为规定中要求对计算结果进行下取整,而我则是在输出的时候对数据位数进行了规定,这可能导致了输出结果又有偏差。查阅资料后我发现对计算结果进行下取整有一个非常简便的方法就是在等式右边用(int)进行强制类型转换,这样就不会产生结果偏差了。
speed = (int) (4 * inputVoltage) - 240;
3.2 封装和重用
        在模拟2中,考虑到每次遍历的目的和结果都不同,每当遇到电阻问题和状态判定问题时我都采用循环遍历的方式进行,但是这样做的结果是代码非常冗余,没有贯彻封装和重用的思想。经过思考以后,我将串并联的状态判定和电阻计算都封装成函数,这样以后大大减少了我的代码量,同时优化了我的结构,经过思考,这样做也是有利于后续迭代的,希望以后能贯彻这样的思想。

      public int judgeSeries(String id);
      public int judgeParallel(String id);
      public double parallelResistance(String id);
      public double calculateResistance(String id);

3.3 实际性
        此次的练习是模拟家居强电电路,但是在一开始的代码实现过程中我没有好好考虑串并联电路的特性,一个是电路状态判定的多样性,串并联电路都应该有三种电路状态,而一开始我只考虑了两种,因此得分很低,二是电路顺序问题,如果存在后序的控制设备,应该对前端设备进行再更新。这两个问题都是非常实际的,而在代码编程的时候也不能忽略模拟内容在实际上的多样性。
4. 改进建议
        在模拟2中,有两种模拟策略,一种是电流,一种是分压,我选择的是电流。但是这样做会使我的电阻列表用处变小,在结构上和设计上存在缺陷,因此我认为可以考虑采取分压的方式。在电阻列表中存储系统总干路每一部分的电阻,然后就可以用串联电路的分压特点计算出每一部分的压降,这样做的好处是减少了一定的误差风险。因为在电流计算上可能存在误差,电阻的计算上也可能存在误差,在计算压降的时候,很可能将两次误差重叠而产生更大而偏差。
        第二个改进建议是,在存储电路时,总是根据输入的引脚存储,实际上我并不是根据引脚来进行设备状态更新的,因此我并不需要那么详细的存储设备引脚信息。在模拟1中我存储的较为详细,在模拟2中我则改为了较为简便的只存储后方内容,这样不仅可以减少存储量,还可以简化引用方式和代码。
5. 总结
        经过这几次的JAVA练习,我对程序设计和JAVA编程有了更深刻的理解。首先时在程序设计时要考虑系统的总体框架,在设计建议中只有单层继承,我在设计时选择二层继承,因此在模拟2中,我只需要对总设备、控制设备和受控设备两个抽象类进行简要调整即可,不需要有大规模的结构调整。
        其次是程序逻辑运行方面,在这次的练习,尤其是电路模拟练习中,由于代码量比较大,且测试点繁多,我在进行代码调整时需要手动运算程序运行结果,亲自运行梳理后才能发现其中的逻辑错误,也让我在代码设计的时候谨慎了很多。
        最后是编程能力,经过这几次的练习,我的编程能力得到了很大的提高,对设计和逻辑思维有了更深刻的理解。

标签:串联,题目,String,PTA,电路,并联,更新,JAVA,设备
From: https://www.cnblogs.com/zhujie-7233/p/18563262

相关文章

  • Java中的公平锁和非公平锁
    公平锁和非公平锁是多线程编程中对锁获取策略的两种不同实现,主要区别在于锁对等待线程的调度方式。公平锁公平锁(FairLock)遵循先来先服务的原则,线程按照请求锁的顺序依次获取锁。特点排队机制:线程请求锁时,如果锁被占用,会进入一个等待队列。当锁被释放时,队列中等待......
  • 【揭秘】JVM类加载器子系统:Java程序员的隐藏武器,你掌握了吗?
    Java虚拟机(JVM)的类加载器子系统是Java平台的核心组件之一,它负责在运行时动态地加载Java类。类加载器子系统通过将类的字节码转换为JVM可以执行的格式,使得Java程序能够实现高度的灵活性和可扩展性。下面将详细解释JVM类加载器子系统的工作原理、结构以及代码示例。打开免费领取......
  • 揭秘JVM性能优化:深入理解运行时数据区,让你的Java应用飞起来!
    Java虚拟机(JVM)的运行时数据区是程序执行期间管理和存储各种信息的关键部分。理解这些区域有助于深入掌握JVM的工作原理和性能优化。以下是对JVM运行时数据区的详细解析:打开免费领取面试资料https://fhos.urlint.cn/cHVLFV一、程序计数器(ProgramCounterRegister)定义:程序计......
  • 基于java和微信小程序实现投票评选系统项目【项目源码+论文说明】计算机毕业设计
    基于java和微信小程序实现投票评选系统演示【内附项目源码+LW说明】摘要越来越多信息化融入到我们生活当中的同时,也在改变着我们的生活和学习方式,当然,变化最明显的除了我们普通民众之外,要数高校学生的生活方式以及校园信息化的变革。智慧是改变生活和生产的一种来源,那么智......
  • Java基础知识(八)
    文章目录异常Exception和Error有什么区别?CheckedException和UncheckedException有什么区别?Throwable类常用方法有哪些?try-catch-finally如何使用?finally中的代码一定会执行吗?如何使用`try-with-resources`代替`try-catch-finally`?异常使用有哪些需要注意的......
  • Java基础知识(七)
    文章目录泛型什么是泛型?有什么作用?泛型的使用方式有哪几种?项目中哪里用到了泛型?反射何谓反射?反射的优缺点?反射的应用场景?注解何谓注解?注解的解析方法有哪几种?SPI何谓SPI?SPI和API有什么区别?SPI的优缺点?序列化和反序列化什么是序列化?什么是反序列化?如果有些字......
  • Java安全-CC链全分析
    前置知识Java访问权限概述对于一个类,其成员(包括成员变量和成员方法)能否被其他类所访问,取决于该成员的修饰词。在Java中,类成员的访问权限修饰词有四个:private,无(包访问权限),protected和public,其权限控制如下表所示:同一个类中同一个包中不同包的子类不同包的无关类public✔......
  • Java 获取本机 IP 地址的方法
    文章目录一、使用InetAddress.getLocalHost二、遍历网络接口获取在Java编程中,若有本机的IP地址的需求,小编来展示一下方法:一、使用InetAddress.getLocalHost一是最基本的获取本机IP地址的方式。示例代码:importjava.net.InetAddress;importjava.net.Un......
  • 项目启动报错java 读取FMavenRepositoryorglz4lz4-java1.7.1lz4-java-1.7.1.jar时出错
    文章目录1.错误呈现2.错误原因3.解决方案3.1方案一:删除jar包,让Maven重新下载(项目重启后可能还是会报错)3.2方案二:删除jar包,手动下载jar包1.错误呈现java:读取F:\MavenRepository\org\lz4\lz4-java\1.7.1\lz4-java-1.7.1.jar时出错;errorinopeningzipfil......
  • 免费送源码:Java+django+MySQL django 教师培训反馈系统 计算机毕业设计原创定制
           目   录摘  要IAbstractII第1章  前  言31.1 研究背景31.2 研究现状31.3 系统开发目标3第2章  系统开发环境62.1HTTP协议62.2HTML网页技术62.3B/S结构62.4django脚本语言72.5MySQL数据库72.6Apache简介8第......