电梯题目总结blog
前言
系统概述
本文介绍了一个基于Java的电梯调度系统模拟实现,该系统模拟了电梯的运行逻辑和乘客请求处理机制。系统核心在于电梯的状态管理、请求队列处理和智能调度算法。
知识点
使用正则表达式拆解输入的乘客请求
使用ArrayList或LinkList来储存外部乘客请求和内部乘客请求,还有对队列的增加和删除。
题量
第一次作业对题目的要求难以理解,花费时间较多,未能在规定时间内写完,大概花了两个星期,和第二次作业是同一时间写完的。
第二次作业在第一次作业的基础上增加了一些要求,因为没完成第一次的代码,所以没有改进,而是直接完成的。
第三次作业在第二次作业上又有了一些修改,大概花了三天完成。
难度
其实这个题目写完之后就感觉不算难,最重要的是搞清楚题目要求,不然很难有思绪。
题目
第一次作业题目
设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求),具体运行规则详见输入输出样例。
输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。
当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:
运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
第二次作业题目
对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类,具体设计可参考如下类图。

电梯运行规则与前阶段单类设计相同,但要处理如下情况:
乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行。乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>
注意:本次作业类设计必须符合如上要求(包含但不限于乘客请求类、电梯类、请求队列类及控制类,其中控制类专门负责电梯调度过程),凡是不符合类设计要求此题不得分,另外,PTA得分代码界定为第一次提交的最高分代码(因此千万不要把第一次电梯程序提交到本次题目中测试)。
输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。
当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:
运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
第三次作业题目
对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客类、队列类以及控制类,具体设计可参考如下类图。

电梯运行规则与前阶段相同,但有如下变动情况:
乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)
注意:本次作业类设计必须符合如上要求(包含但不限于设计电梯类、乘客类、队列类以及控制类),凡是不符合类设计要求此题不得分,另外,PTA得分代码界定为第一次提交的最高分代码(因此千万不要把第一次及第二次电梯程序提交到本次题目中测试)。
输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<请求源楼层,请求目的楼层>,其中,请求源楼层表示乘客发起请求所在的楼层,请求目的楼层表示乘客想要到达的楼层。
当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:
运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
最初的困惑
整体流程模糊:电梯如何从静止状态响应请求?如何在不同状态间转换?请求处理的优先级如何确定?
请求处理逻辑混乱:内部请求和外部请求应该如何存储?如何判断何时应该响应哪种请求?特别是当多个请求同时存在时,处理顺序让我十分困惑。
方向决策困难:电梯在运行过程中如何智能决定是继续当前方向还是改变方向?
题目设计与分析
第一次作业
根据题目要求,要设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求)。
遇到的问题
这道题目对我来说有一定难度,刚开始我没有一点头绪,处理主方法中输入的乘客的请求也是我的盲区之一,也无法正确处理请求间的优先级关系。
解决方案:
1.使用正则表达式处理主方法中输入的乘客的请求。
2.分析处理电梯请求的要求:1)把内部电梯请求与外部请求分别储存在两个链表中;2)当电梯处于空闲状态时,先分析两个链表中的第一个请求哪个最靠近电梯所在楼层,电梯就响应哪个请求;3)当电梯不处于空闲状态时,同电梯运作方向相同且距离电梯所在楼层最近的请求优先;4)如果存在无效楼层输入,直接忽视无效请求,储存下一个有效请求。
第二次作业
题目新增了要求,对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类。乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行。乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>。
遇到的问题
自动忽略高于最高楼层数和最低楼层数的请求没问题,但是忽略连续的相同请求刚开始不知道怎么处理,以为应该在移除响应过的请求的方法中来移除连续的相同请求。
确定电梯运作方向的方法和判断电梯是否停止的方法以及移除响应过的请求的方法起初不清楚该如何设计,不知道这几个方法具体的功能。
解决方案:
1.看到主方法中自动忽略高于最高楼层数和最低楼层数的请求的方式时,对忽略连续的相同请求这个问题就豁然开朗了,对于这些连续的相同请求可以先判断这个请求是否与上一个请求一摸一样,如果一样就不储存至链表中,如果不一样就储存至链表中,继续分析下一个请求。
2.确定电梯运作方向的方法可以通过判断电梯该响应的请求是在电梯上方还是电梯下方,如果在上方电梯方向就向上,如果在下方电梯方向就向下。
3.判断电梯是否停止的方法可以通过判断目标楼层和电梯现在所在楼层是否为同一层,若为同一层就停止并开电梯门,若不为同一楼层就继续向目标楼层上升或下降运作。
4.移除响应过的请求的方法:判断内外部请求链表是否为空,若不为空,判断电梯的目标楼层是内部的还是外部的请求,若是内部的,则移除内部请求链表中的第一个请求,若是外部的,则移除外部请求链表中的第一个请求;若都为空,则电梯为空闲状态。
对源码的分析

上次作业代码没有按时完成,又因是该电梯作业是迭代的是,所以我的第一次与第二次代码为同一个。
第三次作业
乘客请求输入有所变动,乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>。
遇到的问题
大部分问题在第二次作业中得到解决,但对于这句“对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)”不是很理解。
解决方案:
1.用请求目的楼层减去请求源楼层,若为正数,则请求方向为向上,若为负数,则请求方向为向下,把请求源楼层与请求目的楼层以及方向都储存至外部请求链表中,求目标楼层与第二次作业方法相同。
2.外部请求处理后,将该请求的请求目的楼层加入到请求内部队列中,按内部队列处理方法处理。
踩坑心得
通过三次迭代开发,我完成了一个功能完整的电梯调度系统:
第一次作业实现了基础功能,但存在"上帝类"问题,所有逻辑集中在单个类中,导致代码臃肿、难以维护。主要解决了电梯基本运行逻辑和简单请求处理,但方向决策和优先级处理不够完善。
第二次作业进行SRP重构,将系统分解为四个核心类:电梯类专注物理状态,请求类处理数据封装,队列类管理请求集合,控制类负责调度算法。这一阶段最大的突破是建立了清晰的类职责边界,使系统结构更加合理。
第三次作业进一步优化架构,引入乘客类替代请求类,并调整了外部请求的格式和处理逻辑。这一阶段重点解决了请求转换和目的楼层自动加入内部队列的问题。
改进建议
应该降低代码的复杂度,并进一步实现单一职责原则。
总结
关键技术难点与解决方案
1.输入处理:通过正则表达式精确解析不同格式的请求。
2.调度算法:实现了三级优先级处理:,同方向请求优先,顺路捎带处理,反向请求最后处理。
3.请求过滤:在队列类中实现了:,无效楼层过滤(minFloor ≤ floor ≤ maxFloor),重复请求过滤(基于请求特征值比对)。
经验收获
设计原则实践:深刻体会到单一职责原则的价值,合理分解确实能提高可维护性。
调试技巧提升:学会了使用状态日志定位问题,构建最小复现用例,边界条件全面测试,开发方法改进,先设计后编码的重要性,小步快走的迭代价值,版本控制在开发中的必要性。

浙公网安备 33010602011771号