题目集4-6次PTA大作业总结

wcn269 / 2024-06-10 / 原文

前言:

总结4—6次PTA大题目题目集的知识点、题量、难度等情况。

  • 知识点:在原先的基础上题目四依旧是前三个题目的迭代,我个人认为这些题目集难处主要集中在正则表达式的运用以及对整体结构的设计等方面。题目集的最后一个大题都要求了考察面向对象程序与设计中的单一职责原则,迪米特法则和对类的设计,类设计的模板格式、正则表达式的熟悉和使用,而除却题目集四之外,题目集五和六开始加入了抽象类、接口设计考察里氏替换原则而且要求开闭原则的熟悉使用以便进行迭代以提高代码稳定性和扩展性。
  • 题量和难度:我觉得题目虽然说一星期只有一道题,但就难度来说确实有点大,而且题目没看个二十来分钟是完全不能够准确地进行类的设计和代码结构设计的,而我依旧是对于正则表达式依旧没能熟练掌握,很多情况下不知道应该如何将输入框的内容进行分割,这使得我感到难度增大。对于新增加的电路系列题目集来说,我个人认为给予足够的时间应该是可以写出来的,因为电路题目集的第一个题目在我接触之后我心里面是有一种能够写出来的感觉的,但是基于前几次PTA大题的失利对我造成了严重的打击,认为自己就是不能够写出来,而此时段老师给予我们鼓舞让我敢于再次尝试,尝试后发现这题目虽难,尤其是对于正则表达式这一块,但整体而言如果再给我点时间并与同学一起讨论的话我有信心做出来,但由于我起步太晚导致我依旧没能写出来,这也算是一个小遗憾,但我在题目集结束过后我依旧进行构造最后也是成功写了出来。虽说我的PTA没成绩但总的来说。

设计与分析:

  • 第四次大作业第一题
    7-1 答题判题程序-4
    与前三次相比,第四次答题判题程序新增内容为:
  1. 输入选择题题目信息
    题目信息为独行输入,一行为一道题,多道题可分多行输入。

2.输入填空题题目信息
题目信息为独行输入,一行为一道题,多道题可分多行输入。

3.输出顺序变化
只要是正确格式的信息,可以以任意的先后顺序输入各类不同的信息。比如试卷可以出现在题目之前,删除题目的信息可以出现在题目之前等。

经过第三次未达标转而来到第四次时,难度无疑是断崖式的提升,较第三题而言此题变得更加神秘莫测,据说众多选手都在此栽了跟头,而且我也是没看懂题目的意思,只是大概懂了一些内容,并不能够完全将其理解透彻,还是跟第三次作业一样的原因并不能够对源代码进行扩展。而且由于第三题的失利导致我对其产生了畏难心理,故而只花了很少的时间在这给题目上面。

  • 类图设计



根据数据和雷达图分析:
文件大小: 443行代码,是一个相对较小到中等规模的Java文件。

复杂度: 平均复杂度为4.00,表明大部分方法结构较为简单。

最大复杂度: 最复杂的方法是Main.main(),复杂度为9,这意味着它是程序中最复杂的部分。

注释比例: 代码注释比例为2.0%,仍然偏低,增加注释有助于提高代码可读性。

方法平均长度: 平均每个方法8.63条语句,表明方法设计较为紧凑,不过度膨胀。

关键的和建议
Main.main()方法复杂度: 作为入口点,复杂度高达9,可能存在过度集中问题。考虑将其中的功能逻辑拆分为更小的辅助方法,以提高可读性和可维护性。

注释缺乏: 继续强调,尽管代码量不大,但注释的缺乏仍然是一个需要注意的问题。对关键逻辑、类、方法的意图和复杂运算进行注释,有助于未来理解和维护。

控制流: 最大块深度为4,虽然不算太深,但出现在Main.main()方法中,提示可能存在多层逻辑嵌套。简化控制流程,减少嵌套层级,有助于提升代码清晰度。

方法分布: 项目包含3个类,平均每类2.67个方法,表明类设计较为简洁。然而,具体到每个方法的复杂度和长度,还需逐一审查,确保它们遵循单一职责原则。

模块化设计:每个类专注于自己的职责,如Question处理题目信息,TestPaper管理试卷内容,这样的设计使得代码易于理解和扩展。

使用枚举类型:通过定义QuestionType枚举,清晰地区分不同类型的题目,增加了代码的可读性和类型安全性。

伪代码逻辑清晰:虽然提供的代码主要是框架和逻辑概述,但它清晰地展现了处理不同类型输入(单选、多选、填空题、试卷、学生信息、答题卡等)的逻辑,为实现具体功能提供了明确的方向。

  • 总结分析
    代码问题:主要原因还是对于正则表达式的不熟练,类的设计过程中并未遵循开闭原则,即一个类应该对扩展开放,对修改关闭。对于类的设计不够熟练,虽说在补录中成功攻略第一题但我到现在为止任然通过不了测试点,连基本的测试的输出都不能打印出来一个样例,不能将其基本掌握的问题。
    同时我也发现我应该从总体出发,构建一个基本的框架,进而一开始的时候只需要进行扩展类的数量就够了,而非在源代码上进行修改。

  • 第五次大作业第一题
    “家居强电电路模拟程序一”

    • 答题判题程序-5
      本题设计围绕着电路联通的设计而来,要求我们分别设计
  • 控制设备模拟

  • 本题模拟的控制设备包括:开关、分档调速器、连续调速器。

开关:包括0和1两种状态。

开关有两个引脚,任意一个引脚都可以是输入引脚,而另一个则是输出引脚。开关状态为0时,无论输入电位是多少,输出引脚电位为0。当开关状态为1时,输出引脚电位等于输入电位。

分档调速器
按档位调整,常见的有3档、4档、5档调速器,档位值从0档-2(3/4)档变化。本次迭代模拟4档调速器,每个档位的输出电位分别为0、0.3、0.6、0.9倍的输入电压。
连续调速器

没有固定档位,按位置比例得到档位参数,数值范围在[0.00-1.00]之间,含两位小数。输出电位为档位参数乘以输入电压。
所有调速器都有两个引脚,一个固定的输入(引脚编号为1)、一个输出引脚(引脚编号为2)。当输入电位为0时,输出引脚输出的电位固定为0,不受各类开关调节的影响。

所有控制设备的初始状态/档位为0。

控制设备的输入引脚编号为1,输出引脚编号为2。

  • 受控设备模拟

本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。

灯有两种工作状态:亮、灭。在亮的状态下,有的灯会因引脚电位差的不同亮度会有区别。
风扇在接电后有两种工作状态:停止、转动。风扇的转速会因引脚的电位差的不同而有区别。
本次迭代模拟两种灯具。

白炽灯:

亮度在0~200lux(流明)之间。
电位差为0-9V时亮度为0,其他电位差按比例,电位差10V对应50ux,220V对应200lux,其他电位差与对应亮度值成正比。白炽灯超过220V。
日光灯:

亮度为180lux。
只有两种状态,电位差为0时,亮度为0,电位差不为0,亮度为180。
本次迭代模拟一种吊扇。

工作电压区间为80V-150V,对应转速区间为80-360转/分钟。80V对应转速为80转/分钟,150V对应转速为360转/分钟,超过150V转速为360转/分钟(本次迭代暂不考虑电压超标的异常情况)。其他电压值与转速成正比,输入输出电位差小于80V时转速为0。

  • 设计类图

  • 14个类设计
    1.ElectricLoad类设计用于封装电路负载的相关信息,如引脚编号、电压、名称及从名称中提取的数字序号以及负载的工作状态。这种设计有利于在模拟电路系统软件中,以面向对象的方式处理和操作电气负载对象。通过getter和setter方法,外界可以安全地访问和修改这些属性,而isNum()这样的辅助方法则提供了从负载名称中提取额外信息的能力。
    2.Control抽象类的设计目的是为不同的电路控制策略提供一个统一的接口和基础框架。通过定义changeState和loadVoltage这两个抽象方法,强制要求所有继承Control的子类实现如何改变负载状态和如何获取负载电压的逻辑。这在设计复杂的电路控制系统时非常有用,可以确保所有控制类遵循相同的基本交互模式,同时允许它们根据具体需求实现各自独特的功能。
    3.Agent类起到了一个协调者或控制器的角色,它利用DataDeal提供的数据,组织和配置电气系统的各个组件(负载),并依据操作指令调整这些组件的状态。这一过程体现了面向对象编程的思想,通过抽象和封装,使得系统各部分职责清晰,易于理解和维护。


根据数据和雷达图分析:

  • 文件大小: 590行代码,属于中等规模的Java文件。

  • 复杂度: 平均复杂度为2.00,表明大多数方法相对简单,易于理解和维护。

  • 最大复杂度: 最复杂的方法为Agent.initialize(),复杂度为24,这可能是代码审查和优化的重点。

  • 注释比例: 代码中的注释占比非常低(1.5%),增加注释对于提高代码可读性和维护性很重要。

  • 方法数量: 平均每个类有5.21个方法,表明类设计较为均衡。

关键点和建议:

  • 复杂度集中: Agent.initialize()方法是最复杂的,具有最高的复杂度(24)和最多的语句(37),这可能是性能瓶颈或维护难题的来源。考虑重构此方法,将其分解为更小、更易管理的子方法。

  • 注释缺失: 代码的注释率极低,强烈建议增加方法、类及复杂逻辑段落的注释,以提高代码的可读性和团队协作效率。

  • 块深度: 最大块深度达到6,意味着某些逻辑嵌套较深,这可能降低代码的可读性和可维护性。尽量减少嵌套,通过提前返回、方法抽离等方式简化控制流。

  • 方法大小: 平均每个方法2.89条语句,较为理想,但注意少数方法如dealPins()、dealOperations()等较长,也值得审视是否有重构空间。

  • 类和接口: 14个类和接口,表明系统分解得当,但需确保每个类都遵守单一职责原则,避免职责过载。

第五次大作业第二题
家居强电电路模拟程序-2
新增串并联电路模式,并迭代了一个落地扇,
且迭代考虑电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落 地扇的电阻为 20
通过增加电阻和串并联相结合的形式来改变各分路之中的电压进而改变其工作的转速、亮度等数值。
但遗憾的是不会处理其电压之间的关系
如图所示:

  • 总结分析:
    从本次看来,自己没有很好的实现开闭原则,还是在代码里面进行的修改,(直接通过上一个题目集进行扩展)自己的设计没有非常合理,按照自己的初衷,自己仅需要拓展几个子类即可实现程序的实现,下次代码需要好好设计。

踩坑心得:

  • 1.对于电路题目集1中的问题中,我在处理其输入数据的时候
    我先创建了一个LinkedHashSet对象set。LinkedHashSet是一种特殊的集合,它不仅不允许重复元素,还维护了元素的插入顺序。
    Set set = new LinkedHashSet<>(names);
    而后,清空原来的names列表,这是为了准备填充去重后的结果。
    names.clear();
    最后,将set中的所有元素添加回names列表。因为set中已经去除了重复项,所以这样操作可以保证names列表中的元素都是唯一的,且顺序与初次添加时相同。
    names.addAll(set);
    返回去重后的列表: 完成上述步骤后,方法返回去重后的names列表。

  • 很明显这给步骤有点儿重复了。
    改进方法可以为:
    在向names列表添加元素之前,
    通过 if (!names.contains(name))
    检查该名称是否已存在于列表中,以此来避免重复添加。这种方式虽然没有直接使用集合的去重功能,但逻辑相对直观,易于理解。
    如图所示:

改进建议:

  • 1.我们的题目集最后一题都是采取的迭代类型,故而我们应该严格遵循着我们的java七大设计原则,无论是单一职责原则,还是开闭原则,亦或是迪米特法则等等我们都需要在我们类的设计中围绕着它们进行设计并以此进行结构框架的构建。而最为重要的便是理清设计思路,正所谓一个好思路可以抵过大量的重复代码,思索一个好思路也更好让我们对于题目进行进一步的理解,并在思索时对问题抽丝剥茧,一步步剖析问题的本质,进而让我们进一步理解面向对象程序与设计这门课程。

  • 2.根据我们题目要求的行为考虑到我们众多类之间存在着什么关系:是依赖?关联?聚焦?还是泛化?
    许多的行为我们都可以单独拎出来,而非是放在单独某个固定的类中,就比如说我们对数据处理的这个过程就完全可以单独拿出来独自成为一个处理数据的类,进而减少组件之间的耦合性。

  • 3.注释偏少,600行的代码1.5%的注释确实是很少,日后如果还是这样子的代码,完全不利于他人理解,这样就不利于团队之间的沟通和联系,在这方面确实值得改进。

总结:

  • 1.通过此次三大作业的实践操作和练习,我相信只要认真写了的同学都对于正则表达式有了一个更深的理解和认识,但对于我来说正则表达式却还是一个难点,我在有些时候仍就不能对输入的内容进行正确的分割,这样警醒着我要加强这方面的学习理解。

  • 2.在我们的学习方面应熟悉更多方法,如String里面的contains方法、Map类里面的clear()方法、Set类里面的contains()方法,以及使用StringBuffer里面的如append()、insert()、delete()、replace()等方法,使得字符串的构建、修改和操作变得非常灵活方便。

  • 3.对于题目集的解题思路,我觉得还是有必要给同学们更为详细的解答过程,有时候老师发来的思路有某些地方对于同学们并不友好,而且类图中并无注释。

  • 4.对于课程而言,我们确实需要学习极其多的知识,掌握极其多的方法和技巧,而更重要的是打好相应的基础,只有基础足够牢固,我们才能进一步地提升自己的编程能力。故而我建议大家可以去B站、mooc等众多学习软件上进行相应知识的扩充和补充。