单部电梯调度程序总结

1.前言
阅前提示
本人在第一次大作业中顺利完成,在本博客中进行思路和设计的阐述,第二次大作业没有完成但,所以我将进行总结性复盘,第三次大作业四个测试点中依旧有两个测试点没有完成,所以也是进行总结复盘。
1.1 题目一
1.1.1 核心知识点分析
(1)面向对象编程

  • 类的封装设计(ElevatorControl类)
  • 内部类(ExteriorRequest静态内部类)
  • 枚举类型(MovementStatus)
  • 访问控制(private字段,public方法)
  • 构造方法和方法重载
    (2)数据结构应用
  • 集合框架(LinkedList用于请求队列)
  • 自定义数据结构(ExteriorRequest类)
  • 队列操作(add, removeFirst, getFirst, isEmpty)
    (3)算法实现
  • LOOK调度算法的基本框架
  • 状态机管理
  • 方向判断逻辑
  • 请求优先级处理
    1.1.2题量评估
    代码规模:200-300行
    主类:Main
    辅助类:ElevatorControl
    内部类:ExteriorRequest
    枚举:MovementStatus
    1.1.3难度
    难度中等
    已经实现的难点:
  • 复杂的条件判断逻辑
  • 多状态管理
  • 队列动态操作

1.2题目二
1.2.1核心知识点分析
(1)面向对象编程

  • 类的单一职责设计:按照题目要求进行了职责分离
  • Elevator类:专门负责电梯状态管理和基本操作
  • OuterRequest类:封装外部请求数据
  • Main类:负责程序入口和输入处理
  • 枚举类型应用:Direction和ElevatorState枚举
  • 访问控制:合理的private字段和public方法设计
    (2)数据结构应用
  • 集合框架:使用Queue接口和LinkedList实现
  • 自定义数据结构:OuterRequest请求封装类
  • 队列操作:offer、peek、poll等操作
    (3)算法实现
  • LOOK调度算法框架:基本的电梯调度逻辑
  • 状态机管理:通过枚举管理电梯状态
  • 方向判断逻辑:基于请求目标楼层调整运行方向
  • 请求优先级处理:内外请求的协调处理

1.2.2代码规模评估

  • 代码行数:200-300
  • 类方法:4个
  • 方法:约15个

1.2.3难度分析

  • 难度等级:中等偏上
  • 难点:
    复杂的条件判断和状态转换
    多队列协同管理
    重复请求过滤逻辑
    边界条件处理

1.3题目三
1.3.1 核心知识点分析
(1)面向对象编程

  • 类的封装设计:严格按照单一职责原则设计4个核心类
  • Elevator类:负责电梯状态管理
  • Passenger类:封装乘客请求数据
  • RequestQueue类:管理请求队列
  • Controller类:实现调度算法
    (2)数据结构应用
  • 集合框架:使用LinkedList管理请求队列
  • 自定义数据结构:Passenger类封装请求信息
  • 队列操作:add、removeIf、isEmpty等操作
  • 排序算法:基于方向的动态排序
    (3)算法实现
  • LOOK调度算法改进:支持外部请求到内部请求的转换
  • 状态机管理:通过方向枚举管理运行状态
  • 方向判断逻辑:同向优先原则
  • 请求优先级处理:动态排序内部请求队列
    1.3.2题量评估
    代码规模:约250行(符合200-300行范围)
    主类:Main
    辅助类:Elevator、Passenger、RequestQueue、Controller
    枚举:Direction
    符合类设计要求:包含电梯类、乘客类、队列类、控制类
    1.3.3难度
    难度等级:中等偏上
    已实现难点:
    复杂的方向判断和状态转换逻辑
    外部请求到内部请求的动态转换
    多队列协同管理和优先级处理
    边界条件和完善的错误处理

2.设计与分析
2.1题目一
2.1.1类图设计

题目一类图

设计思路
状态模式: 通过MovementStatus管理电梯状态
命令模式: 将请求封装为对象(ExteriorRequest)
队列管理: 使用LinkedList管理请求队列
分层架构: 控制逻辑与用户界面分离
类之间的关系
组合关系​:
ElevatorControl与 ExteriorRequest是强组合关系
外部请求对象生命周期完全由电梯控制类管理
聚合关系​ :
ElevatorControl与两个LinkedList是聚合关系
请求队列包含在电梯控制中,但有独立的存在意义
依赖关系​ :
Main类依赖 ElevatorControl类
通过方法参数传递依赖
使用关系:
ElevatorControl使用 MovementStatus枚举
用于状态管理和逻辑判断

2.1.2主要算法分析
1.方向调整算法
private void adjustMovementDirection()
{
if (interiorRequests.isEmpty() && exteriorRequests.isEmpty()) return;

if (!interiorRequests.isEmpty() && !exteriorRequests.isEmpty()) {
    handleBothRequestsPresent();  // 混合请求处理
} else if (!interiorRequests.isEmpty()) {
    handleInteriorRequestsOnly(); // 仅内部请求
} else {
    handleExteriorRequestsOnly(); // 仅外部请求
}

}

分析:
贪心策略:总是优先处理当前方向的请求
方向优化:避免不必要的方向切换

2.停靠决策算法
private boolean shouldStopForExteriorRequest(ExteriorRequest request) {
if (interiorRequests.isEmpty()) return true; // 无内部请求时直接停靠

int nextInterior = interiorRequests.getFirst();
return request.desiredDirection.equals(movingDirection) ||
        ("UP".equals(request.desiredDirection) && nextInterior > request.level) ||
        ("DOWN".equals(request.desiredDirection) && nextInterior < request.level);

}

停靠条件分析:
方向匹配:外部请求方向与电梯当前方向一致
路径兼容:外部请求在内部请求的路径上
优先级:内部请求优先于外部请求

3.请求处理算法分析

private final LinkedList interiorRequests = new LinkedList<>();
private final LinkedList exteriorRequests = new LinkedList<>();

数据结构选择分析:
LinkedList:适合频繁的插入删除操作
FIFO处理:但实际不是严格的FIFO,存在方向优化
搜索效率:O(n)搜索,但通过方向优化减少搜索范围

移动策略算法
SCAN算法变种
private void executeSingleStep() {
presentLevel += "UP".equals(movingDirection) ? 1 : -1; // 单向移动直到边界
operationalState = MovementStatus.IN_MOTION;
displayCurrentStatus();
}
电梯算法:类似磁盘调度的SCAN算法
方向保持:当前方向处理完所有请求后才反转

2.2题目二
题目二我没有正确完成,于是这个板块我将进行对比分析重点阐述我个人思路和错误点
2.2.1类图设计

题目二类图

设计思路
1.双队列架构:
内部请求队列:LinkedList管理电梯内按钮请求
外部请求队列:LinkedList管理楼层外呼请求
去重集合:使用HashSet确保请求唯一性
状态管理模式:
通过Direction枚举管理三种运行状态(上行、下行、空闲)
状态转换基于请求分布和当前楼层
2.单一职责原则应用
ExternalRequest:封装外部请求数据,纯数据类,重写equals/hashCode
Elevator_DoubleQueue:电梯核心调度逻辑,双队列管理,距离优先算法
Main:程序入口和IO处理,请求解析和电梯启动
3.设计模式应用
策略模式:​ 通过不同的目标选择策略实现灵活调度
状态模式:​ 电梯运行方向作为状态进行管理
命令模式:​ 请求封装为对象进行统一处理

2.2.2主要算法分析
1.核心调度算法 - 距离优先策略

点击查看代码
// 关键算法:按距离选择最近目标楼层
private Integer getTargetByDistance() {
    List<Integer> candidateFloors = new ArrayList<>();
    
    // 1. 收集同向内部请求
    for (int floor : internalQueue) {
        if ((direction == Direction.UP && floor > currentFloor) ||
            (direction == Direction.DOWN && floor < currentFloor)) {
            candidateFloors.add(floor);
        }
    }
    
    // 2. 收集同向外部队列
    for (ExternalRequest req : externalQueue) {
        if (req.dir == direction &&
            ((direction == Direction.UP && req.floor > currentFloor) ||
             (direction == Direction.DOWN && req.floor < currentFloor))) {
            candidateFloors.add(req.floor);
        }
    }
    
    // 3. 选择距离最近的楼层
    return candidateFloors.stream()
        .min(Comparator.comparingInt(f -> Math.abs(f - currentFloor)))
        .orElse(null);
}

分析:
1.距离优先:始终选择最近的请求,提高效率
2.方向一致性:优先处理同向请求,减少转向次数
3.执行流程:初始化方向 → 选择最近目标 → 逐层移动 → 处理当前请求 → 重新选择目标

2.移动控制算法

点击查看代码
private void moveToTarget(int targetFloor) {
    while (currentFloor != targetFloor) {
        currentFloor += direction == Direction.UP ? 1 : -1;
        printStatus();  // 确保每层都输出
    }
}

分析:逐层移动,确保输出格式符合要求

3.请求处理算法分析

点击查看代码
private void processCurrentFloorRequests() {
    boolean needStop = false;
    
    // 内部请求处理(FIFO)
    while (!internalQueue.isEmpty() && internalQueue.getFirst() == currentFloor) {
        internalQueue.removeFirst();
        internalSet.remove(currentFloor);
        needStop = true;
    }
    
    // 外部请求处理(方向匹配)
    while (!externalQueue.isEmpty()) {
        ExternalRequest extHead = externalQueue.getFirst();
        if (extHead.floor == currentFloor && extHead.dir == direction) {
            externalQueue.removeFirst();
            externalSet.remove(extHead);
            needStop = true;
        } else {
            break;
        }
    }
    
    if (needStop) {
        // 输出开关门信息
    }
}

数据结构选择分析:
LinkedList:支持高效的头部删除和尾部添加(O(1)复杂度)
HashSet:快速去重检查(O(1)查找复杂度

去重算法
1.去重数据结构
// 去重集合
private final Set internalSet = new HashSet<>();
private final Set externalSet = new HashSet<>();
2.内部请求去重逻辑
public void addInternal(int floor) {
if (isValid(floor) && !internalSet.contains(floor)) { // ← 这里检查是否已存在
internalQueue.addLast(floor);
internalSet.add(floor); // ← 这里添加到去重集合
}
}
3.外部请求去重处理
public void addExternal(int floor, Direction dir) {
ExternalRequest req = new ExternalRequest(floor, dir);
if (isValid(floor) && !externalSet.contains(req)) { // ← 这里检查是否已存在
externalQueue.addLast(req);
externalSet.add(req); // ← 这里添加到去重集合
}
}
4.请求处理时同步清理
// 处理内部请求时同步清理去重集合
internalQueue.removeFirst();
internalSet.remove(currentFloor); // ← 同步移除

// 处理外部请求时同步清理去重集合
externalQueue.removeFirst();
externalSet.remove(extHead); // ← 同步移除

2.3题目三依旧先说明我的代码的设计思路
2.3.1类图设计

题目三类图

2.3.2设计思路

  • 极致单一职责原则:
    7个高度专一类:每个类只负责一个明确定义的功能
    数据与逻辑分离:状态控制器只存数据,处理器只含逻辑
    策略模式极致化:每个算法步骤都有专用类负责
  • 架构模式应用:
    协调者模式:ElevatorSystemCoordinator协调所有组件
    策略模式:不同选择器实现不同算法策略
    状态模式:双重枚举精确管理运行状态
    命令模式:ExternalCall封装外部请求命令

2.3.3主要算法分析
1.系统协调流程:

点击查看代码
public void start() {
    directionDecider.initializeDirection(elevator, storage);  // 1. 初始化方向
    printInitialStatus();                                     // 2. 初始状态
    
    while (!storage.isEmpty()) {
        Integer target = targetSelector.findNextTarget(elevator, storage); // 3. 选择目标
        
        if (target == null) {
            directionDecider.reverseDirection(elevator);     // 4. 无目标则转向
            target = targetSelector.findNextTarget(elevator, storage);
        }
        
        movementExecutor.moveToTarget(elevator, target);      // 5. 移动到目标
        requestProcessor.processCurrentFloor(elevator, storage); // 6. 处理请求
    }
}

2.智能方向初始化算法

点击查看代码
public void initializeDirection(ElevatorStateController elevator, RequestStorageManager storage) {
    List<Integer> allFloors = new ArrayList<>();
    allFloors.addAll(storage.getInternalRequests());
    for (ExternalCall call : storage.getExternalRequests()) {
        allFloors.add(call.getFloor());
    }

    if (!allFloors.isEmpty()) {
        int closest = allFloors.stream()
                .min(Comparator.comparingInt(f -> Math.abs(f - elevator.getCurrentFloor())))
                .orElse(elevator.getCurrentFloor());
        elevator.setDirection(closest > elevator.getCurrentFloor() ? Direction.UP : Direction.DOWN);
    }
}

3.请求处理算法分析

private final LinkedList interiorRequests = new LinkedList<>();
private final LinkedList exteriorRequests = new LinkedList<>();

4.数据结构设计创新
1.双结构队列设计:
LinkedList:保持请求顺序,支持高效的头尾操作
HashSet:提供O(1)复杂度的存在性检查
同步维护:添加删除时同步更新两个结构
2.状态管理
// 精确的状态转换控制
elevator.setState(ElevatorState.MOVING); // 移动中状态
elevator.setState(ElevatorState.STOPPED); // 停靠状态

3.踩坑心得
3.1题目一
3.1.1最终代码的几张流程图
1.整体控制算法流程图
整体控制算法流程图
2.停靠决策算法流程图
停靠决策算法流程图

3.1.2 先前版本和最终版本的不同比较

1.类结构对比

代码点击查看,因为好像如果使用插入代码他不换行
前版本

点击查看代码
enum Direction { IDLE, UP, DOWN }
enum Status { STOPPED, MOVING, OPENING, CLOSING }
class Elevator {
    // 三个独立队列:内部、外部上行、外部下行
    private Queue<Integer> innerQueue;
    private Queue<Integer> outerUpQueue;
    private Queue<Integer> outerDownQueue;
}

现版本

点击查看代码
enum MovementStatus { IDLE, IN_MOTION }
class ElevatorControl {
    // 两个简单队列:内部请求、外部请求
    private final LinkedList<Integer> interiorRequests;
    private final LinkedList<ExteriorRequest> exteriorRequests;
}

差异

前版本:过度设计,3个独立队列增加了复杂度

现版本:符合题目要求的"内部请求"和"外部请求"分类

2.算法流程图对比

前版本
前版本算法流程图
每次都要全局扫描

现版本
现版本算法流程图
简单循环,每次只处理最紧急的请求,符合题目要求的逐步处理逻辑

3.核心算法逻辑对比

方向决策逻辑
前版本

点击查看代码
private Direction determineNextDirection() {
    // 复杂的全局扫描和距离计算
    if (direction == Direction.UP) {
        boolean hasUpRequest = innerQueue.stream().anyMatch(f -> f > currentFloor) 
                             || !outerUpQueue.isEmpty();
        // ... 大量复杂逻辑
    }
}
现版本
点击查看代码
private void adjustMovementDirection() {
    // 简单直观:只关注队列头部的请求
    if (!interiorRequests.isEmpty() && !exteriorRequests.isEmpty()) {
        handleBothRequestsPresent(); // 比较两个队列的第一个请求
    }
    // ... 简洁的逻辑
}

停靠处理逻辑
前版本

点击查看代码
private boolean hasRequestAtCurrentFloor() {
    // 同时检查三个队列,逻辑复杂
    if (innerQueue.contains(currentFloor)) return true;
    if (direction == Direction.UP && outerUpQueue.contains(currentFloor)) return true;
    if (direction == Direction.DOWN && outerDownQueue.contains(currentFloor)) return true;
    return false;
}
现版本
点击查看代码
private boolean processInteriorRequest() {
    // 只处理队列头部的请求,先进先出
    if (!interiorRequests.isEmpty() && interiorRequests.getFirst() == presentLevel) {
        interiorRequests.removeFirst();
        return true;
    }
    return false;
}

分析

题目期望
1.内部请求队列 + 外部请求队列
2.单步移动,每次处理当前楼层的请求
3.相对简单的先进先出+方向优化
前版本设计错点
1.设计为内部队列 + 外部上行队列 + 外部下行队列(过度设计)
2.移动逻辑不符合,前版本为方向性移动,可能连续移动多层才停靠
3.请求处理顺序为基于距离和方向的复杂优先级调度
现版本符合题意关键点
1.只有两个队列,清晰明了
2.每次只关注最紧急的请求
3.严格单步移动,符合电梯实际行为
3.只有基本的状态枚举

用例测试结果对比分析

前版本

点击查看代码
1
20
<3,UP>
<5>
<6,DOWN>
<7>
<3>
end
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: 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

具体错误对比

联想截图_20251122113501
问题代码:

1.初始楼层未设置

点击查看代码
public void run() {
    while (true) {
        Direction nextDir = determineNextDirection();
        if (nextDir == Direction.IDLE) {
            break;
        }
        direction = nextDir;
        status = Status.MOVING;
        
        while (true) {
            // 直接移动,没有输出初始楼层
            if (direction == Direction.UP) {
                currentFloor++;  // 直接从1层跳到2层
            }
            // ...
        }
    }
}

正确做法:应该在移动前输出当前楼层

点击查看代码
public void commenceOperation() {
    displayCurrentStatus();  // 先输出初始状态
    
    while (hasPendingTasks()) {
        performMovementCycle();
    }
}

2.方向判断逻辑错误

点击查看代码
private boolean hasRequestAtCurrentFloor() {
    if (direction == Direction.UP && outerUpQueue.contains(currentFloor)) {
        return true;
    }
    // 只检查同方向的外部请求
}

问题:​ 当电梯从7楼下行到6楼时,虽然6楼有DOWN请求,但电梯当前方向是UP(在转向时没有正确处理),导致无法识别6楼的请求。

正确代码:逐步移动。

点击查看代码
private void executeSingleStep() {
    presentLevel += "UP".equals(movingDirection) ? 1 : -1;
    operationalState = MovementStatus.IN_MOTION;
    displayCurrentStatus();  // 每次移动都输出
}

3.队列管理缺陷

点击查看代码
private void processCurrentFloorRequests() {
    // 只移除当前方向的请求
    if (direction == Direction.UP) {
        outerUpQueue.removeIf(floor -> floor == currentFloor);
    }
    // 下行队列的请求可能被忽略
}

当电梯处理完上行请求转向下行时,下行队列中的请求没有被正确处理。

正确代码:考虑了顺路请求的情况,即使方向不完全匹配,只要顺路就停靠。

点击查看代码
private boolean shouldStopForExteriorRequest(ExteriorRequest request) {
    return request.desiredDirection.equals(movingDirection) ||
            ("UP".equals(request.desiredDirection) && nextInterior > request.level) ||
            ("DOWN".equals(request.desiredDirection) && nextInterior < request.level);
}

3.2题目二,重点把迭代要求中错误版本(我的)和正确版本(正确版本是满分的同学的)进行对比分析
3.2.1去重机制
1.我的版本
// 基于Set的完全去重 - 过滤所有重复请求(包括非连续的)
if (isValid(floor) && !internalSet.contains(floor)) {
internalQueue.addLast(floor);
internalSet.add(floor);
}
分析 使用了HashSet进行完全去重,这会过滤掉所有重复请求(包括非连续的),而题目要求只过滤连续的相同请求。 比如:使用HashSet会过滤掉所有重复请求,包括非连续的 例如输入:<3><5><3>会被过滤为<3><5>,但题目只要求过滤连续重复
2.正确代码:
// 基于"上一次请求"的去重 - 只过滤连续的相同请求
if (lastInnerRequest != null && lastInnerRequest == floor) {
return; // 忽略连续的相同请求
}

3.2.2调度和请求处理算法
1.我的版本
使用"距离优先"算法,选择最近的同向请求作为目标
按距离重新排序请求,破坏了原有的输入顺序

2.正确版本
使用传统的LOOK算法,逐层移动,基于队列头部请求决定方向
严格按照队列顺序处理请求(FIFO)

3.2.3重点错误在于去重,从流程图上分析
我的版本去重逻辑流程图

去重(我的)

正确版本去重逻辑流程图

去重(正确的)

3.2.4重点错误在于去重,从用例输出结果上分析
首先列出一个明显反应我的代码错误的用例
1.我的版本用例和输出:

点击查看代码
1
20
<3,UP>
<3,UP>
<5>
<5>
<5>
<6,DOWN>
<7>
<7>
<3>
<22,DOWN>
<5,DOWN>
<3>
<30>
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
Open Door # Floor 5
Close Door
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door

2.正确版本的用例和输出
点击查看代码
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
Open Door # Floor 5
Close Door
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
Current Floor: 2 Direction: DOWN
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door

详细分析错误的原因

点击查看代码
1
20
<3,UP>     ← 外部请求,楼层3,上行
<3,UP>     ← 连续重复,应被过滤
<5>        ← 内部请求,楼层5
<5>        ← 连续重复,应被过滤  
<5>        ← 连续重复,应被过滤
<6,DOWN>   ← 外部请求,楼层6,下行
<7>        ← 内部请求,楼层7
<7>        ← 连续重复,应被过滤
<3>        ← 内部请求,楼层3(非连续重复,应保留)
<22,DOWN>  ← 无效楼层(22>20),应被忽略
<5,DOWN>   ← 外部请求,楼层5,下行(非连续重复,应保留)
<3>        ← 内部请求,楼层3(连续重复,应被过滤)
<30>       ← 无效楼层(30>20),应被忽略
end

1.我的代码
< 3,UP> ← 保留
<5> ← 保留
<6,DOWN> ← 保留
<7> ← 保留
<5,DOWN> ← 保留(但可能因Set去重而被误过滤)
关键问题:​ 第二段代码使用HashSet,会过滤掉所有重复请求,包括:
<3>(第二个)被过滤 → 但这是非连续重复,应该保留!
<5,DOWN>可能被误过滤(如果Set认为与内部请求<5>冲突)
调度逻辑差异:
距离优先:选择最近的同向请求,破坏原有顺序
算法不同:产生与传统电梯不同的移动模式
输出异常:可能跳过某些楼层或改变服务顺序
2.正确代码
< 3,UP> ← 保留第一个
<5> ← 保留第一个
<6,DOWN> ← 保留
<7> ← 保留第一个
<3> ← 非连续重复,保留
<5,DOWN> ← 非连续重复,保留
调度逻辑:
初始方向:基于最近请求确定方向
逐层处理:按照LOOK算法顺序服务请求
方向转换:当同方向无请求时改变方向
预期输出特征:
按照请求的"逻辑顺序"处理
保持电梯的传统调度行为
输出符合题目示例格式

3.3题目三,依旧是重点把迭代要求中错误版本(我的)和正确版本(正确版本是满分的同学的)进行对比分析
3.3.1去重机制
去重机制和题目二的错误点一样,我的代码把所有的重复请求都过滤掉了,其实只要过滤掉连续的重复请求即可

3.3.2调度和请求处理算法
依旧是和题目二调度算法错误点相同
所以测试点1、2没过
联想截图_20251122213511

4.改进建议
4.1题目一
可读性 :枚举名规范化

点击查看代码
// 当前:中英文混合,不够规范
enum MovementStatus {
    IDLE, IN_MOTION
}

// 改进:统一使用英文命名
enum ElevatorState {
    IDLE, MOVING, STOPPED
}

enum Direction {
    UP, DOWN, NONE
}

数据结构优化

点击查看代码
// 当前:使用LinkedList,查找效率低
private final LinkedList<Integer> interiorRequests = new LinkedList<>();
private final LinkedList<ExteriorRequest> exteriorRequests = new LinkedList<>();

// 改进建议:使用更适合的数据结构
private final PriorityQueue<Integer> interiorRequests; // 可按方向排序
private final Map<Integer, List<ExteriorRequest>> exteriorRequestsByFloor; // 按楼层索引

请求去重处理

点击查看代码
// 当前:可能重复添加相同请求
public void registerInteriorCall(int level) {
    interiorRequests.add(level); // 可能重复
}

// 改进:添加去重检查
public void registerInteriorCall(int level) {
    if (!interiorRequests.contains(level)) {
        interiorRequests.add(level);
    }
}

4.2题目二和题目三的改进方向
4.2.1 去重算法修正

点击查看代码
// 正确实现连续去重
private Integer lastInnerRequest = null;
private OuterRequest lastOuterRequest = null;

public void addInternalRequest(int floor) {
    if (lastInnerRequest != null && lastInnerRequest == floor) {
        return; // 只过滤连续重复
    }
    // ... 正常处理
}

4.2.2 调度算法回归传统

点击查看代码
// 使用传统LOOK算法而非距离优先
private void adjustDirection() {
    // 基于队列头部的简单方向判断
    if (currentDir == Direction.UP) {
        hasSameDirRequest = hasHigherRequests(current);
    }
    // ... 简洁逻辑
}

4.2.3 架构简化
// 回归4类简洁设计
class Elevator // 电梯状态
class Passenger // 乘客请求
class Controller // 调度控制
class RequestQueue // 队列管理

5.总结
学习收获

  • 技术层面:
    深入理解了LOOK电梯调度算法
    掌握了面向对象设计的基本原则
    学会了需求分析和架构设计的方法论
  • 经验层面:
    认识到"简单设计"的重要性
    理解了测试驱动开发的价值
    培养了系统化的问题分析能力

5.2 需要进一步学习的领域
算法设计:需要加强传统算法的理解和应用
架构平衡:在简单和复杂之间找到合适的平衡点
测试方法论:建立更系统的测试策略
需求分析:提高准确理解需求的能力

5.3 对课程的建议

  • 教学方面:
    提供更多样例分析:展示正确和错误的对比案例
    阶段性代码评审:在关键节点提供设计反馈
    详细的需求说明:明确边界条件和期望行为
  • 实践方面:
    增量式开发指导:分步骤引导复杂系统的构建
    调试技巧培训:教授系统化的调试方法论
    架构设计模式:介绍常用的设计模式和应用场景
posted @ 2025-11-22 21:48  23207104-曹婷  阅读(15)  评论(0)    收藏  举报