题目集5-7总结分析
前言:
这三次的题目集整体对我来说较为偏难,但是通过写这些个题目集中的题目,不管是题目集5中的正则表达式,题目集6和7中的类的设计以及后面电梯问题的迭代1.0,2.0,3.0。都让我对于java,面向对象这门课程有了更深刻的理解,也让我对于java这一门编程语言更加的熟悉。虽然老师觉得这次的题目集并没啥难度,但是我认为对于我们这种刚刚才开始接触java-面向对象程序设计基础的我们还是有一定的难度的。尤其是需要我们将固有的思想加以转换,就是要将面向程序的思想转换为面向对象这一思想。就我经过写我这几次的题目集之后最深的感悟就在于这两种思想上的差异,前者更加注重于你去让一个东西干什么,就好比如这次的电梯实验,使用前者的思想就是我去让电梯去干嘛干嘛,给电梯写一个方法,可能这种思想处理简单点的问题比较容易,但是也有着极大的缺点。那就是如果需要考虑的情况比较多,方法比较繁琐的时候,代码就会显得特别长,就需要耗费大量的功夫。而后者的思想更加注重于我去构造电梯这一个类,把电梯这一个类写出来之后他就会自己去干你想让他去干的事情,这种思想处理那种比较繁琐的就相对于简单多了,而且我认为以这种思想思考问题就感觉自己就像是上帝一样,这也让我对这一门课程又多添了一些兴趣。
设计与分析:
首先来分析一下单部电梯调度程序,单部电梯调度程序根据电梯运行过程详解附件可知其运用了两种主要的算法,一个是LOOK 算法,一个是优先队列算法。
LOOK 算法:文档中电梯运行采用了类似 LOOK 算法的思想。LOOK 算法在磁盘调度中用于优化磁头移动,在电梯场景里,电梯会根据当前运行方向优先处理同方向的请求,直到该方向没有请求时,才改变方向处理反方向请求。这种方式减少了电梯的无效移动,提高了运行效率。电梯在向上运行时,会处理所有向上的请求,如先处理电梯外 3 楼向上请求和电梯内去 5 楼、7 楼的请求,直到向上方向请求处理完,再向下处理请求。使用LOOK 算法有以下优点减少无效移动,提高运行效率:LOOK 算法的核心优势在于,电梯在运行时会优先处理同方向的请求,直至该方向请求全部处理完毕才改变方向。这有效避免了电梯频繁地来回折返,极大地减少了无效移动距离和时间。在有多个楼层请求的情况下,电梯不会因为中途出现反向请求而频繁改变运行方向,能够连续高效地服务同方向的乘客,提升了整体运行效率。符合现实场景需求:该算法模拟了现实中人们对电梯运行的期望,与日常乘坐电梯的体验相符。乘客通常希望电梯能尽快响应自己的请求,LOOK 算法优先处理同方向请求的机制,让电梯在同一行程中尽可能多地满足同向乘客需求,减少了乘客等待时间,提高了乘坐的便捷性和满意度。降低系统开销:减少电梯的无效移动,不仅降低了能源消耗,还减轻了电梯机械部件的磨损,降低了维护成本和系统运行开销。从长期运行的角度来看,有助于延长电梯的使用寿命,提高系统的稳定性和可靠性。
优先队列算法:在处理请求时,使用优先队列来管理请求队列。电梯内部请求队列和外部上下行请求队列各自独立,且在判断处理哪个请求时,优先考虑同方向且距离近的请求。例如在选择下一个处理请求时,会比较电梯内和电梯外同方向请求的楼层距离当前楼层的远近,选择距离最近的请求进行处理 。以下是使用优先队列算法的优点:高效的请求管理:优先队列能够根据预设的优先级规则,快速定位并处理最符合条件的请求。在电梯场景中,通过将同方向且距离近的请求设置为高优先级,优先队列可以确保电梯在众多请求中迅速选择最优目标。在处理多个请求时,优先队列能快速筛选出距离当前楼层最近的同方向请求,使电梯的运行路径更加合理,减少不必要的停留和等待。灵活适应动态请求:随着新请求不断加入,优先队列能够自动调整元素顺序,始终保持高优先级请求在队列前端。即使在电梯运行过程中收到新请求,优先队列也能快速重新评估优先级,使电梯及时响应更紧急或更有利的请求,有效应对动态变化的请求场景。简化代码逻辑:使用优先队列算法,代码在处理请求选择时逻辑更加清晰简洁。相较于复杂的手动排序和筛选逻辑,优先队列的内置功能可以大大减少代码量,降低编程难度,提高代码的可读性和可维护性。开发人员可以更专注于电梯运行的核心逻辑实现,减少因复杂请求管理逻辑导致的错误。


点击查看代码
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
// 定义电梯运行方向枚举
enum Direction {
UP, DOWN, STILL
}
// 定义电梯运行状态枚举
enum Status {
STOPPED, MOVING, OPENING, CLOSING
}
// 电梯类
class Elevator {
private int minFloor;
private int maxFloor;
private int currentFloor;
private Direction direction;
private Status status;
private Queue<Integer> internalRequests;
private Queue<Integer> externalUpRequests;
private Queue<Integer> externalDownRequests;
// 构造函数初始化电梯属性
public Elevator(int minFloor, int maxFloor) {
this.minFloor = minFloor;
this.maxFloor = maxFloor;
this.currentFloor = minFloor;
this.direction = Direction.STILL;
this.status = Status.STOPPED;
internalRequests = new LinkedList<>();
externalUpRequests = new LinkedList<>();
externalDownRequests = new LinkedList<>();
}
// 添加请求到相应队列,并检查请求的有效性
public void addRequest(String request) {
if (request.equalsIgnoreCase("end")) {
return;
}
if (request.contains(",")) {
String[] parts = request.substring(1, request.length() - 1).split(",");
int floor = Integer.parseInt(parts[0]);
String dir = parts[1];
if (floor < minFloor || floor > maxFloor) {
System.out.println("无效楼层请求: " + floor);
return;
}
if ("UP".equals(dir)) {
externalUpRequests.add(floor);
} else if ("DOWN".equals(dir)) {
externalDownRequests.add(floor);
}
} else {
int floor = Integer.parseInt(request.substring(1, request.length() - 1));
if (floor < minFloor || floor > maxFloor) {
System.out.println("无效楼层请求: " + floor);
return;
}
internalRequests.add(floor);
}
}
// 处理请求的核心方法
public void processRequests() {
while (!internalRequests.isEmpty() ||!externalUpRequests.isEmpty() ||!externalDownRequests.isEmpty()) {
if (direction == Direction.STILL) {
determineInitialDirection();
} else if (direction == Direction.UP) {
processUpRequests();
} else {
processDownRequests();
}
}
if (status != Status.STOPPED) {
status = Status.STOPPED;
}
}
// 确定电梯初始运行方向
private void determineInitialDirection() {
if (!externalUpRequests.isEmpty()) {
direction = Direction.UP;
} else if (!externalDownRequests.isEmpty()) {
direction = Direction.DOWN;
} else if (!internalRequests.isEmpty()) {
int firstInternal = internalRequests.peek();
if (firstInternal > currentFloor) {
direction = Direction.UP;
} else {
direction = Direction.DOWN;
}
}
}
// 处理向上的请求
private void processUpRequests() {
boolean hasUpRequest = false;
while (!externalUpRequests.isEmpty() && externalUpRequests.peek() >= currentFloor) {
moveToFloor(externalUpRequests.poll());
hasUpRequest = true;
}
while (!internalRequests.isEmpty() && internalRequests.peek() >= currentFloor) {
moveToFloor(internalRequests.poll());
hasUpRequest = true;
}
if (!hasUpRequest) {
if (!externalDownRequests.isEmpty() ||!internalRequests.isEmpty()) {
direction = Direction.DOWN;
processDownRequests();
} else {
direction = Direction.STILL;
}
}
}
// 处理向下的请求
private void processDownRequests() {
boolean hasDownRequest = false;
while (!externalDownRequests.isEmpty() && externalDownRequests.peek() <= currentFloor) {
moveToFloor(externalDownRequests.poll());
hasDownRequest = true;
}
while (!internalRequests.isEmpty() && internalRequests.peek() <= currentFloor) {
moveToFloor(internalRequests.poll());
hasDownRequest = true;
}
if (!hasDownRequest) {
if (!externalUpRequests.isEmpty() ||!internalRequests.isEmpty()) {
direction = Direction.UP;
processUpRequests();
} else {
direction = Direction.STILL;
}
}
}
// 控制电梯移动到指定楼层
private void moveToFloor(int targetFloor) {
if (targetFloor == currentFloor) {
openDoor();
return;
}
if (targetFloor > currentFloor) {
while (currentFloor < targetFloor) {
currentFloor++;
status = Status.MOVING;
direction = Direction.UP;
System.out.println("Current Floor: " + currentFloor + " Direction: " + direction);
}
} else {
while (currentFloor > targetFloor) {
currentFloor--;
status = Status.MOVING;
direction = Direction.DOWN;
System.out.println("Current Floor: " + currentFloor + " Direction: " + direction);
}
}
openDoor();
}
// 模拟电梯开门操作
private void openDoor() {
status = Status.OPENING;
System.out.println("Open Door # Floor " + currentFloor);
status = Status.CLOSING;
System.out.println("Close Door");
}
}
public class ElevatorSimulation {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int minFloor = scanner.nextInt();
int maxFloor = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
Elevator elevator = new Elevator(minFloor, maxFloor);
String request;
while (!(request = scanner.nextLine()).equalsIgnoreCase("end")) {
elevator.addRequest(request);
}
elevator.processRequests();
scanner.close();
}
}
点击查看代码
enum Direction {
UP, DOWN, STILL
}
// 定义电梯运行状态枚举
enum Status {
STOPPED, MOVING, OPENING, CLOSING
}
Direction 枚举:用于表示电梯的运行方向,包含 UP(向上)、DOWN(向下)和 STILL(静止)三种状态。这样可以让代码中对电梯方向的表示更加清晰和易读,避免使用简单的数字或字符来表示方向而导致的混淆。
Status 枚举:用于表示电梯的运行状态,有 STOPPED(停止)、MOVING(移动中)、OPENING(开门)和 CLOSING(关门)四种状态。通过枚举类型,我们可以明确电梯在不同时刻的状态,便于后续的逻辑处理和状态管理。
Elevator 类
点击查看代码
class Elevator {
private int minFloor;
private int maxFloor;
private int currentFloor;
private Direction direction;
private Status status;
private Queue<Integer> internalRequests;
private Queue<Integer> externalUpRequests;
private Queue<Integer> externalDownRequests;
点击查看代码
public Elevator(int minFloor, int maxFloor) {
this.minFloor = minFloor;
this.maxFloor = maxFloor;
this.currentFloor = minFloor;
this.direction = Direction.STILL;
this.status = Status.STOPPED;
internalRequests = new LinkedList<>();
externalUpRequests = new LinkedList<>();
externalDownRequests = new LinkedList<>();
}
点击查看代码
public void addRequest(String request) {
if (request.equalsIgnoreCase("end")) {
return;
}
if (request.contains(",")) {
String[] parts = request.substring(1, request.length() - 1).split(",");
int floor = Integer.parseInt(parts[0]);
String dir = parts[1];
if (floor < minFloor || floor > maxFloor) {
System.out.println("无效楼层请求: " + floor);
return;
}
if ("UP".equals(dir)) {
externalUpRequests.add(floor);
} else if ("DOWN".equals(dir)) {
externalDownRequests.add(floor);
}
} else {
int floor = Integer.parseInt(request.substring(1, request.length() - 1));
if (floor < minFloor || floor > maxFloor) {
System.out.println("无效楼层请求: " + floor);
return;
}
internalRequests.add(floor);
}
}
点击查看代码
public void processRequests() {
while (!internalRequests.isEmpty() ||!externalUpRequests.isEmpty() ||!externalDownRequests.isEmpty()) {
if (direction == Direction.STILL) {
determineInitialDirection();
} else if (direction == Direction.UP) {
processUpRequests();
} else {
processDownRequests();
}
}
if (status != Status.STOPPED) {
status = Status.STOPPED;
}
}
点击查看代码
private void determineInitialDirection() {
if (!externalUpRequests.isEmpty()) {
direction = Direction.UP;
} else if (!externalDownRequests.isEmpty()) {
direction = Direction.DOWN;
} else if (!internalRequests.isEmpty()) {
int firstInternal = internalRequests.peek();
if (firstInternal > currentFloor) {
direction = Direction.UP;
} else {
direction = Direction.DOWN;
}
}
}
点击查看代码
private void processUpRequests() {
boolean hasUpRequest = false;
while (!externalUpRequests.isEmpty() && externalUpRequests.peek() >= currentFloor) {
moveToFloor(externalUpRequests.poll());
hasUpRequest = true;
}
while (!internalRequests.isEmpty() && internalRequests.peek() >= currentFloor) {
moveToFloor(internalRequests.poll());
hasUpRequest = true;
}
if (!hasUpRequest) {
if (!externalDownRequests.isEmpty() ||!internalRequests.isEmpty()) {
direction = Direction.DOWN;
processDownRequests();
} else {
direction = Direction.STILL;
}
}
}
点击查看代码
private void processDownRequests() {
boolean hasDownRequest = false;
while (!externalDownRequests.isEmpty() && externalDownRequests.peek() <= currentFloor) {
moveToFloor(externalDownRequests.poll());
hasDownRequest = true;
}
while (!internalRequests.isEmpty() && internalRequests.peek() <= currentFloor) {
moveToFloor(internalRequests.poll());
hasDownRequest = true;
}
if (!hasDownRequest) {
if (!externalUpRequests.isEmpty() ||!internalRequests.isEmpty()) {
direction = Direction.UP;
processUpRequests();
} else {
direction = Direction.STILL;
}
}
}
点击查看代码
private void processDownRequests() {
boolean hasDownRequest = false;
while (!externalDownRequests.isEmpty() && externalDownRequests.peek() <= currentFloor) {
moveToFloor(externalDownRequests.poll());
hasDownRequest = true;
}
while (!internalRequests.isEmpty() && internalRequests.peek() <= currentFloor) {
moveToFloor(internalRequests.poll());
hasDownRequest = true;
}
if (!hasDownRequest) {
if (!externalUpRequests.isEmpty() ||!internalRequests.isEmpty()) {
direction = Direction.UP;
processUpRequests();
} else {
direction = Direction.STILL;
}
}
}
点击查看代码
private void openDoor() {
status = Status.OPENING;
System.out.println("Open Door # Floor " + currentFloor);
status = Status.CLOSING;
System.out.println("Close Door");
}
点击查看代码
public class ElevatorSimulation {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int minFloor = scanner.nextInt();
int maxFloor = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
Elevator elevator = new Elevator(minFloor, maxFloor);
String request;
while (!(request = scanner.nextLine()).equalsIgnoreCase("end")) {
elevator.addRequest(request);
}
elevator.processRequests();
scanner.close();
}
}
起初,面对电梯编程这个领域,我仿佛置身于一片迷雾之中,到处都是难以跨越的障碍。语法错误就像一个个隐藏在暗处的小怪兽,时不时地跳出来捣乱;逻辑错误更是如同错综复杂的迷宫,让我在其中迷失方向。看着屏幕上密密麻麻的错误提示,那种挫败感几乎将我淹没,甚至让我对自己的专业选择产生了动摇。我花费大量时间与编译器“死磕”,每一次的尝试都像是一场艰苦的战斗,身心俱疲。
然而,每当我成功攻克一个难题,让代码顺利运行起来,那一刻的喜悦和成就感是无法用言语来形容的。这就像是在漫长的黑夜中,终于迎来了黎明的曙光,让我重新燃起了对编程的热情,也让我坚信之前所有的努力都不会白费。在这个过程中,我深刻地认识到,编程不仅仅是代码的堆砌,更是一场对耐心和细心的严峻考验。每一个细微的错误都可能导致整个程序无法正常运行,所以必须要养成严谨的编程习惯。
调试代码的过程虽然充满艰辛,但也让我收获了宝贵的技能和经验。有一次,在处理电梯的复杂调度逻辑时,程序出现了异常,但我却怎么也找不到问题的根源。于是,我静下心来,运用调试技巧,一步步地设置断点,仔细观察变量的变化情况。经过长时间的排查,终于发现是一个极其细微的逻辑判断失误。那一刻,那种恍然大悟的感觉让我瞬间充满了信心,也让我对调试代码有了更深的理解和掌握。
随着学习的深入,我对编程的理解也发生了改变。我逐渐明白,优秀的代码并非追求表面的华丽和复杂,而是要注重效率、可读性和可维护性。高效的代码能够在保证功能的前提下,快速处理各种任务;易读的代码方便自己和他人理解程序的逻辑,降低维护成本;可维护的代码则能够在需求发生变化时,轻松进行修改和扩展。
在学习过程中,与同学们的交流也给了我很大的帮助。我们定期组织学习讨论,分享彼此在电梯编程中遇到的问题以及解决方法。有时候,大家还会一起为了调试一个复杂的程序而共同努力。在交流中,我发现不同的人有着不同的思路和方法,这种思想的碰撞让我开阔了眼界,也让我学会了从多个角度去思考问题。比起单纯地抄袭代码,这种交流学习的方式更能激发我的思考,让我真正掌握知识的核心。
尽管现在我的代码还存在很多不足之处,但我并不气馁。我清楚地认识到自己在算法优化方面还有很长的路要走。目前编写的代码在处理大规模数据或复杂逻辑时,效率明显不够理想,这让我意识到需要不断学习新的算法知识,优化代码结构,提升代码的性能表现。同时,设计模式的应用也是我需要深入研究的方向。合理运用设计模式能够让代码更加模块化、结构化,提高代码的可维护性、可扩展性和复用性,从而使程序更加健壮和灵活。
未来,我将继续努力,不断学习和实践,在电梯编程乃至整个编程领域中不断探索前进。我相信,只要保持这份热情和坚持,我一定能够写出更加优秀的代码,实现自己的编程梦想。

浙公网安备 33010602011771号