南昌航空大学-ptajava

前言
本次对PTA作业进行总结,共三道Java大题,为电梯调度程序的迭代开发。涉及到基础Java语言的运用,look电梯调度算法的实现,队列结构的使用,枚举类型运用,类设计,迭代开发能力等知识点。

第一次作业:单部电梯调度程序
设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求)。

输出格式:
模拟电梯的运行过程,输出方式如下:
运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door

输入样例:
1
20
❤️,UP>
<5>
<6,DOWN>
<7>
<3>
End

输出样例:
Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
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
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Open Door # Floor 6
Close Door
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door

第二次作业:单部电梯调度程序(类设计)
对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类。
电梯运行规则与前阶段单类设计相同,但要处理如下情况:
乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行
乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>

输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。
当输入“end”时代表输入结束(end不区分大小写)。

输出格式:
模拟电梯的运行过程,输出方式如下:
运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door

输入样例:
1
20
❤️,UP>
<5>
<6,DOWN>
<7>
<3>
End

输出样例:
Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
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
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Open Door # Floor 6
Close Door
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door

第三次作业:单部电梯调度程序(类设计-迭代)
对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客类、队列类以及控制类。
电梯运行规则与前阶段相同,但有如下变动情况:
乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)

输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<请求源楼层,请求目的楼层>,其中,请求源楼层表示乘客发起请求所在的楼层,请求目的楼层表示乘客想要到达的楼层。
当输入“end”时代表输入结束(end不区分大小写)。

输出格式:
运模拟电梯的运行过程,输出方式如下:
行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door

输入样例:
1
20
<5,4>
<5>
<7>
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
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Open Door # Floor 5
Close Door
Current Floor: 4 Direction: DOWN
Open Door # Floor 4
Close Door

设计与分析
第一次作业
测试:

863f1893ed3313397cc1616d0845af75

class Elevator {
// 属性:当前楼层、方向、状态、请求队列
// 方法:移动、处理请求、LOOK算法
}
算法可以直接实现,逻辑还是比较清晰的,但是示例过了提交不过,代码细节还是不够到位,逻辑性差而且可读性也不好。

第二次作业
类设计
4a32094075044a06567af3e3e79f87c4

测试:
46f36cf96733c7bc8d03253b30f26456

class PassengerRequest // 乘客请求类
class RequestQueue // 请求队列管理类
class Elevator // 电梯状态类
class Controller // 调度控制类
这次实验主要考察类设计,设计了请求,电梯状态,调度等,逻辑比上次更清晰,但是设计类的时候还是又小逻辑错误,不过条理清晰也方便修改。

第三次作业
类设计
bdf01bbac1bdc1b4dcc6ec2f272983dc

测试:
cf654219d0962cedd430878380f1b55d

class Passenger { // 乘客类
-Integer sourceFloor
-Integer destinationFloor
}

class RequestQueue {
-LinkedList internalRequests
-LinkedList externalRequests
+addDestinationAsInternalRequest()
}
这次依旧是示例过了提交没过,最后运行超时,题目难度对我来说还是有点高的,逻辑错误一堆,三次作业都没过,有点学艺不精了。
踩坑心得
这三次作业都想的太简单了,做的时候又绕了好几个弯子, 做第三次作业时,我想在第二次作业的基础上做简单修改,结果发现新的PASSENGER类与原有请求类结构有冲突,然后又重构整个类关系。

改进建议
别把所有功能都塞在一个类里,像调度算法应该单独抽出来,做成可以随时替换的模块。这样以后想换别的算法就不用重新大改。同时得养成边写边测试的习惯。每次改完代码跑一遍测试。而且要学会用工具帮我们管代码。比如用deeepseek等来帮助每次改动,提高代码质量。这些工具能让我们少踩很多坑,有时候报错的原因可能仅仅是符号错误或者把main打成mian这种低级错误。可维护性也很重要,多写注释、文档,但别写废话。关键是要把为什么这么设计说清楚,过几个月自己再看还能看懂。

总结
第一次作业:掌握了look电梯调度的基本逻辑,能够应用队列数据结构在调度中应用。
第二次作业:对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),设计了跟复杂的类关系,学会了请求队列的管理和无效输入处理方法。
第三次作业:对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,对代码进行最新迭代,重构,对架构进行了优化。
第一次作业我把电梯怎么运行的逻辑写出来,功能都直接塞进去,虽然能跑起来,但是太过混乱。第二次作业分做了不同的类,整体代码变得更有条理,第三次迭代难度的大得多,只能把部分功能做出来,虽然最后提交不过,但是此次学习增进了对新算法编程的学习能力以及应对能力。

posted @ 2025-11-22 19:31  中苏  阅读(0)  评论(0)    收藏  举报