题目集5~7的总结

一、前言

  在5到7次的题目练习里,我学会了用类写代码、生成随机数,还掌握了用正则表达式处理字符串的方法,弄明白了不同类之间的关系。这几次题目难度就像爬楼梯,越往后越难,但特别锻炼我们的思维能力,给编程打下了坚定的基础。 最让我印象深的是第一道电梯题,当时可把我难住了,整整琢磨了一个星期才搞明白,后面还去请教了老师才弄清楚逻辑。虽然花的时间长,但学到的东西也最多。其他题目虽然也费了几个小时,但比第一次电梯题轻松多了。后面两次电梯题,其实就是在第一次的基础上稍微修改一下就可以正确了(第二次主要是将单独的Main类拆分成多个类,而第三次主要是修改了外部电梯的请求),很快就能做出来。

  题量 难度 知识点
题目集五 5 较难 正则表达式
题目集六 3 中等 类与对象,正则表达式
题目集七 3 较难 类与对象,随机数,正则表达式

二、设计与分析

  与三道电梯题相比,其他题目便索然无味。接下来分别对三次的电梯题进行分析。

  (1)第一次电梯题

    题目重点聚焦在电梯运行核心逻辑的实现上,无需运用类的相关知识,只要能把电梯调度、响应等基础逻辑理顺写对就可以了。

    我的类图

    

    类的设计:

    • Main类:处理输入的数据,创建电梯类、电梯外请求队列和电梯内请求队列。用循环调用电梯运行方法,操控电梯。
    • Elevator类:成员变量( 最小楼层数、最大楼层数、当前楼层、运行方向、运行状态、电梯内请求队列和电梯外请求队列)。已及相应的构造方法和get\set方法。有着电梯相关信息包括请求队列,有电梯运行、开门、寻找下次目标楼层、转向等方法。

      SourceMontor分析结果:

    

     

      

      分析

  该代码整体复杂度良好(平均2.39),代码嵌套较深(20处4层嵌套),注释率11.6%略低,控制流复杂度适中(25.5%),方法平均长度合理(8.05行)。

心得

  花费时间长:这道题花费了我一个星期左右的时间才正确,是因为一开始没有很好的理解题目就开始编写代码,导致底层逻辑与题目不符,重写2~3次才较为理解题目意思。尤其是第一次,误以为所有请求是编输入边处理,后面与朋友相谈才了解要一次性输入(后面老师也在群里进行提醒了)。而第二次编写时,依旧没完全弄清楚什么是优先处理同方向的请求,导致逻辑依旧存在着问题,当时我看时间所剩不多,便去和老师交谈,发现了其他问题,并改正了。到了第三次编写的时候,已经开始有人陆陆续续答案正确,我看着答案错误的提示,心有点乱,但通过与朋友的交谈发现了问题所在,那就是第一次处理请求的时候没有考虑同方向最近的请求,而是直接取了电梯外部的请求。有了这次的经历,我充分了解了编写代码之前应该先捋清楚题目要求,而不应该只了解一星半点儿就开始相应的编程,导致浪费大量的时间。

  代码逻辑:这次题目还没有要求应用单一职责原则(SRP),导致很多变量和方法都存在于Main类和Elevator类中,从而增加了部分代码的复杂度,降低了复用性。而且在调试的时候,往往难以找到错误所在的具体位置,增加了调试花费时间。而且在上完一天的课后,重新打开代码往往需要从头到尾进行理解,确定代码完成的具体程度,但是代码中注释过少,增加了理解时间。若注释完全,则可省下不少时间,更有利于编写代码。有了这些经历,我了解到单一职责原则和在代码中进行注释的重要性。也浅浅的意识到类设计的好处所在。

  (2)第二次电梯题

  题目重点聚焦在对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类。

    我的类图

    

    类的设计:

    • Main类:创建控制类,调用控制类中的请求处理方法、第一次运行方向判断方法和电梯运行方法。
    • Elevator类:成员变量( 最小楼层数、最大楼层数、当前楼层、运行方向和运行状态),已及相应的构造方法和get\set方法。
    • Controller类:成员变量(队列类对象和电梯类对象),已及相应的构造方法和get\set方法。成员方法(处理请求信息,提取字符串中数字,电梯第一次运行方向判定,寻找同方向目标楼层,电梯运行,向上运行,向下运行,开门,转向)。
    • RequestQueue类:成员变量(电梯内请求队列和电梯外请求队列),以及相应的构造方法和get\set方法。成员方法(清除对应的对头楼层)。
    • ExternalRequest类:成员变量(楼层和目标方向),以及相应的构造方法和get\set方法。

    SourceMontor分析结果:

    

    

    

      分析

  这段代码整体复杂度处于可控范围(平均1.31),代码结构存在6处5层深度嵌套(行号126)和7处4层嵌套,偏低的注释率(10.1%),控制流复杂度(21.4%分支语句)和方法平均长度(5.51语句)处于合理区间。

      心得

   第二次电梯作业的代码可读性太差了。注释率从第一次的11.6%降到10.1%,调试的时候自己都看不懂自己写的代码。特别是隔几个小时再来看,简直像破解密码一样。这个坏毛病必须改。

  在一开始做这道题的时候,依旧和第一次一样,没有仔细的阅读题目意思,而是直接去修改代码,然后答案正确。但后面经过老师和朋友们的提醒,才发现必须进行类设计,而且检测的代码是第一次满分的代码,否则提交正确也没有任何分数。而我由于急于求成,没有进行类设计,违背题目要求,也就导致这道题我没分了,白忙活一场,这就是急着抄近道的代价。这次也是给我急于求成的一次教训吧,提醒着我在编程之前应该仔细阅读要求,不能毛毛躁躁,自以为是以后一定要先看清楚题目要求再动手。

  在进行类分类的过程中,我发现类图中存储数据的变量是链表,而我第一次使用的是数组。对于请求信息来说,数量是不固定的,用数组存储存在弊端,应该使用链表或者集合更为方便。但在我修改过程中,发现使用链表会有应该很麻烦的情况存在——链表为空。而且查找数据时,如果链表为空就会直接报错。但如果所有有关的if语句都添加判断链表是否为空会比较麻烦,而我就耍了一个小聪明,在链表的尾部再添加一个节点(数据值全为0的节点)。这样已经可以避免链表为空的情况了,但给第三次作业埋了雷。不管怎么样,用了链表存储后,感觉更加快捷,也学习到了链表的使用方式。

  这次代码仅仅是对上次代码进行类设计,但是代码却多了整整80行,在刚开始类设计的时候,我就有了一种感觉——类设计怎么感觉让代码变得更复杂了。对于初学者的我来说,也许不能充分体会类设计的好处。但通过这道题,我却知道了,弄清楚类与类之间的关系,并不简单,需要反复推敲,反复琢磨。探究类与类之间的关系就像绘制一幅复杂的地图,具有挑战性。

  (3)第三次电梯题

  题目重点聚焦在对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP)。

    我的类图

    

    类的设计:

    • Main类:创建控制类,调用控制类中的请求处理方法、第一次运行方向判断方法和电梯运行方法。
    • Elevator类:成员变量( 最小楼层数、最大楼层数、当前楼层、运行方向和运行状态),已及相应的构造方法和get\set方法。还有判断楼层是否有效的方法。
    • Controller类:成员变量(队列类对象和电梯类对象),已及相应的构造方法和get\set方法。成员方法(处理请求信息,提取字符串中数字,电梯第一次运行方向判定,寻找同方向目标楼层,电梯运行,向上运行,向下运行,开门,转向)。
    • RequestQueue类:成员变量(电梯内请求队列和电梯外请求队列),以及相应的构造方法和get\set方法。还有在队尾添加节点的方法。
    • ExternalRequest类:成员变量(请求楼层、目标楼层和目标方向),以及相应的构造方法和get\set方法。

    SourceMontor分析结果:

    

    

    

      分析

  这段代码整体复杂度处于可控范围(平均1.31),代码结构存在5处5层深度嵌套(行号122)和13处4层嵌套,偏低的注释率(8.3%),控制流复杂度(19.4%分支语句)和方法平均长度(5.40语句)处于合理区间。

      心得

  注释率低:代码注释率比上次还低了2.0%,虽然这样可能在编程的时候节省了注释时间,但是存在着不小的隐患。若日后重新对代码进行迭代,则需要先花费大量的时间去弄清楚代码逻辑。而且在团队合作中依旧如此,则不利于队友之间的相互配合,徒增负担。从今开始应该养成注释的习惯。

  整体来说,这道题我也改得迷迷糊糊,按照题目要求分析后,我觉得只要修改一下存储数据的那个方法就可以解决,但是最后还有一个运行超时,我找了好久,最后才发现是判断请求重复的if语句没有写全。这一点点粗心大意让我多花了好几个小时(找运行超时的情况)。但是我后来又发现把这个if语句去掉依旧答案正确,就感觉白忙活一场。不过,可以引以为戒,在以后编程的时候多加注意。

三、采坑心得

  题目集五

(1)没有理解好什么是串行处理,误以为输入一个数据就处理一个数据,然后花费几个小时将样例能够正确通过后,才发现要一次性输入。

(2)误用equals比较字符串是否相等来判断是否结束,导致非零返回。题目说了不用区分大小写,应该使用equalsIgnoreCase进行比较。

 

(3)没有真正的理解题目优先处理同方向请求的意思

输入样例
 1
20
<9>
<5,DOWN>
<7,DOWN>
<2>
<3>
end
我错误的输出
 Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Current Floor: 8 Direction: UP
Current Floor: 9 Direction: UP
Open Door # Floor 9
Close Door
Current Floor: 8 Direction: DOWN
Current Floor: 7 Direction: DOWN
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Current Floor: 2 Direction: DOWN
Open Door # Floor 2
Close Door
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
正确输出
  Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Current Floor: 8 Direction: UP
Current Floor: 9 Direction: UP
Open Door # Floor 9
Close Door
Current Floor: 8 Direction: DOWN
Current Floor: 7 Direction: DOWN
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Open Door # Floor 5
Close Door
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Current Floor: 2 Direction: DOWN
Open Door # Floor 2
Close Door
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Open Door # Floor 7
Close Door

(4)搭建框架时十分模糊不清,并且方法没有做到单一职责原则,导致后续调试,修改什么费劲,最后迫不得已只能重写。

(5)没有弄清楚电梯转向的情况,后续和老师交谈才充分了解到。

输入样例
 1
20
<10,UP>
<13,DOWN>
<14,DOWN>
<11>
<3>
end
我的错误输出
 Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Current Floor: 8 Direction: UP
Current Floor: 9 Direction: UP
Current Floor: 10 Direction: UP
Open Door # Floor 10
Close Door
Current Floor: 11 Direction: UP
Open Door # Floor 11
Close Door
Current Floor: 12 Direction: UP
Current Floor: 13 Direction: UP
Open Door # Floor 13
Close Door
Current Floor: 12 Direction: DOWN
Current Floor: 11 Direction: DOWN
Current Floor: 10 Direction: DOWN
Current Floor: 9 Direction: DOWN
Current Floor: 8 Direction: DOWN
Current Floor: 7 Direction: DOWN
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Current Floor: 8 Direction: UP
Current Floor: 9 Direction: UP
Current Floor: 10 Direction: UP
Current Floor: 11 Direction: UP
Current Floor: 12 Direction: UP
Current Floor: 13 Direction: UP
Current Floor: 14 Direction: UP
Open Door # Floor 14
Close Door
正确输出
  Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Current Floor: 8 Direction: UP
Current Floor: 9 Direction: UP
Current Floor: 10 Direction: UP
Open Door # Floor 10
Close Door
Current Floor: 11 Direction: UP
Open Door # Floor 11
Close Door
Current Floor: 12 Direction: UP
Current Floor: 13 Direction: UP
Open Door # Floor 13
Close Door
Current Floor: 14 Direction: UP
Open Door # Floor 14
Close Door
Current Floor: 13 Direction: DOWN
Current Floor: 12 Direction: DOWN
Current Floor: 11 Direction: DOWN
Current Floor: 10 Direction: DOWN
Current Floor: 9 Direction: DOWN
Current Floor: 8 Direction: DOWN
Current Floor: 7 Direction: DOWN
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door

题目集六

(1)第二次电梯题没有看清楚题目要求,忽略了类设计这个要求,导致第二次电梯题没有分数。

(2)第三次电梯题将数组改为链表时没有充分考虑到链表存在着空的情况,导致报错信息多。

题目集七

(1)考虑了重复的情况,但是没有充分考虑到什么情况才是重复

(2)来自题目集六的坑,在链表尾部加了数据全为0的节点。导致到达电梯外请求后,将目标楼层加入电梯内部请求队列时,没有考虑到尾部的虚假节点。

(3)在处理电梯外部请求信息时,将请求方向搞反了

四、改进建议

(1)目前代码注释太少不利于理解,在后续的改进过程应该增加注释。

(2)在Controller类中的processInformation()方法的复杂度太高,处理了多种请求信息,可以考虑将其拆分成几个方法,降低复杂度。

(3)代码还不能处理最低楼层为负数的情况,后续可以增加该情况。

(4)Controller类中的功能太多,而且混杂,可以尝试再拆分为几个类,做好单一职责原则。

五、总结

(1)学习到的内容

  通过三次题目集练习,我学习到了正则表达式的基础匹配功能,可用于判断字符串是否符合特定格式要求;理解链表的基本结构和操作逻辑,能够使用相应的方法进行操作;掌握类与对象的基本概念,初步了解类设计的基本原则,能够对简单情况进行类设计;学会使用随机数生成方法,并掌握基础调试工具的使用方法,能够更好的排除错误。意识到了单一职责原则和代码注释的重要性。

(2)仍需学习和提升的地方

  在学习过程中,我发现在正则表达式的复杂文本处理、链表的高级应用、类设计的单一职责原则落实等方面存在不足,后续应进行相应的学习。还发现使用电脑码字的速度有点慢,应进行相应的练习。

(3)建议和意见

    • 希望老师多分享一些实用的工具。
    • 在出题时多设计一些测试点,在题目中多提供一些测试样例。
    • 适当和我们分享一些软件工程未来的方向,发展趋势。
posted @ 2025-04-19 20:09  无妄清野  阅读(30)  评论(0)    收藏  举报