yyhyyj

导航

 

前言
这次的电梯大作业于我来说是真的难,大部分的分数都没有得到,所以这个Blog只能当个检讨文章了。大作业主要考察我们的设计类的能力,就是面向对象的能力,本人还是不够理解这方面,所以没做出来,哭死。

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

输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。

电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。
当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:

运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
输入样例:
在这里给出一组输入。例如:

1
20
< 3,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
我的源码:
`import java.util.;
import java.util.regex.
;

enum Direction {
UP, DOWN, IDLE
}

enum State {
STOPPED, MOVING, OPENING, CLOSING
}

public class Elevator {
private int minFloor;
private int maxFloor;
private int currentFloor;
private Direction direction;
private State state;
private TreeSet innerRequests;
private TreeSet outerUpRequests;
private TreeSet outerDownRequests;

public Elevator(int minFloor, int maxFloor) {
    this.minFloor = minFloor;
    this.maxFloor = maxFloor;
    this.currentFloor = minFloor;
    this.direction = Direction.IDLE;
    this.state = State.STOPPED;
    this.innerRequests = new TreeSet<>();
    this.outerUpRequests = new TreeSet<>();
    this.outerDownRequests = new TreeSet<>(Collections.reverseOrder());
}

public void addRequest(String request) {
    Matcher outerMatcher = Pattern.compile("<(\\d+),(UP|DOWN)>").matcher(request);
    Matcher innerMatcher = Pattern.compile("<(\\d+)>").matcher(request);

    try {
        if (outerMatcher.matches()) {
            int floor = Integer.parseInt(outerMatcher.group(1));
            String dir = outerMatcher.group(2);
            if (floor < minFloor || floor > maxFloor) return;
            if (dir.equals("UP")) {
                outerUpRequests.add(floor);
            } else {
                outerDownRequests.add(floor);
            }
        } else if (innerMatcher.matches()) {
            int floor = Integer.parseInt(innerMatcher.group(1));
            if (floor < minFloor || floor > maxFloor) return;
            innerRequests.add(floor);
        }
    } catch (NumberFormatException ignored) {}
}

public void run() {
    if (innerRequests.isEmpty() && outerUpRequests.isEmpty() && outerDownRequests.isEmpty()) {
        return;
    }

    determineDirection();
    if (direction == Direction.IDLE) return;

    while (true) {
        if (direction == Direction.UP) {
            currentFloor++;
        } else {
            currentFloor--;
        }
        System.out.printf("Current Floor: %d Direction: %s%n", currentFloor, direction);

        boolean shouldStop = false;
        if (innerRequests.contains(currentFloor)) {
            innerRequests.remove(currentFloor);
            shouldStop = true;
        }
        if (direction == Direction.UP && outerUpRequests.contains(currentFloor)) {
            outerUpRequests.remove(currentFloor);
            shouldStop = true;
        } else if (direction == Direction.DOWN && outerDownRequests.contains(currentFloor)) {
            outerDownRequests.remove(currentFloor);
            shouldStop = true;
        }

        if (shouldStop) {
            System.out.println("Open Door # Floor " + currentFloor);
            System.out.println("Close Door");
        }

        if (!hasMoreRequestsInCurrentDirection()) {
            direction = (direction == Direction.UP) ? Direction.DOWN : Direction.UP;
            if (!hasMoreRequestsInCurrentDirection()) break;
        }

        if (innerRequests.isEmpty() && outerUpRequests.isEmpty() && outerDownRequests.isEmpty()) break;
    }
    direction = Direction.IDLE;
}

private void determineDirection() {
    if (direction != Direction.IDLE) return;

    NavigableSet<Integer> upCandidates = new TreeSet<>();
    upCandidates.addAll(innerRequests.tailSet(currentFloor + 1, true));
    upCandidates.addAll(outerUpRequests.tailSet(currentFloor + 1, true));

    NavigableSet<Integer> downCandidates = new TreeSet<>(Collections.reverseOrder());
    downCandidates.addAll(innerRequests.headSet(currentFloor, false));
    downCandidates.addAll(outerDownRequests.headSet(currentFloor, false));

    Integer closestUp = upCandidates.isEmpty() ? null : upCandidates.first();
    Integer closestDown = downCandidates.isEmpty() ? null : downCandidates.first();

    int distUp = closestUp != null ? closestUp - currentFloor : Integer.MAX_VALUE;
    int distDown = closestDown != null ? currentFloor - closestDown : Integer.MAX_VALUE;

    if (distUp <= distDown && closestUp != null) {
        direction = Direction.UP;
    } else if (closestDown != null) {
        direction = Direction.DOWN;
    } else {
        direction = Direction.IDLE;
    }
}

private boolean hasMoreRequestsInCurrentDirection() {
    if (direction == Direction.UP) {
        return !innerRequests.tailSet(currentFloor + 1, false).isEmpty() ||
               !outerUpRequests.tailSet(currentFloor + 1, false).isEmpty();
    } else if (direction == Direction.DOWN) {
        return !innerRequests.headSet(currentFloor, false).isEmpty() ||
               !outerDownRequests.headSet(currentFloor, false).isEmpty();
    }
    return false;
}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int min = scanner.nextInt();
    int max = scanner.nextInt();
    scanner.nextLine();

    Elevator elevator = new Elevator(min, max);
    String line;
    while (!(line = scanner.nextLine()).equalsIgnoreCase("end")) {
        elevator.addRequest(line);
    }
    elevator.run();
}

}`
代码分析:

题目集6:
对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(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
输入样例1:
在这里给出一组输入。例如:

1
20
< 3,UP>
<5>
<6,DOWN>
<7>
<3>
end
输出样例1:
在这里给出相应的输出。例如:

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
输入样例2:
在这里给出一组输入。例如:

1
20
❤️,UP>
❤️,UP>
<5>
<5>
<5>
<6,DOWN>
<7>
<7>
<3>
<22,DOWN>
<5,DOWN>
<30>
END
我的源码:
`import java.util.*;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int minFloor = Integer.parseInt(scanner.nextLine());
int maxFloor = Integer.parseInt(scanner.nextLine());
RequestManager requestManager = new RequestManager(minFloor, maxFloor);
String line;
while (true) {
line = scanner.nextLine().trim();
if (line.equalsIgnoreCase("end")) break;
requestManager.processInput(line);
}
ElevatorCore elevator = new ElevatorCore(minFloor, maxFloor);
Scheduler scheduler = new Scheduler(elevator, requestManager);
scheduler.executeOperations();
}
}

// 请求处理类:验证并存储请求
class RequestManager {
private final Set innerRequests = new HashSet<>();
private final Set outerUpRequests = new HashSet<>();
private final Set outerDownRequests = new HashSet<>();
private final int minFloor;
private final int maxFloor;

public RequestManager(int minFloor, int maxFloor) {
    this.minFloor = minFloor;
    this.maxFloor = maxFloor;
}

public void processInput(String input) {
    ElevatorRequest request = new ElevatorRequest(input, minFloor, maxFloor);
    if (!request.isValid()) return;

    if (request.getType() == RequestType.INNER) {
        innerRequests.add(request);
    } else {
        if (request.getDirection() == Direction.UP) {
            outerUpRequests.add(request);
        } else {
            outerDownRequests.add(request);
        }
    }
}

public Set<Integer> getInnerTargets() {
    Set<Integer> targets = new HashSet<>();
    for (ElevatorRequest r : innerRequests) targets.add(r.getFloor());
    return targets;
}

public Set<Integer> getUpwardCalls() {
    Set<Integer> calls = new HashSet<>();
    for (ElevatorRequest r : outerUpRequests) calls.add(r.getFloor());
    return calls;
}

public Set<Integer> getDownwardCalls() {
    Set<Integer> calls = new HashSet<>();
    for (ElevatorRequest r : outerDownRequests) calls.add(r.getFloor());
    return calls;
}

public void clearRequest(int floor, Direction dir) {
    innerRequests.removeIf(r -> r.getFloor() == floor);
    if (dir == Direction.UP) {
        outerUpRequests.removeIf(r -> r.getFloor() == floor);
    } else {
        outerDownRequests.removeIf(r -> r.getFloor() == floor);
    }
}

public boolean hasPendingRequests() {
    return !innerRequests.isEmpty() || !outerUpRequests.isEmpty() || !outerDownRequests.isEmpty();
}

}

// 请求实体类:封装请求数据
class ElevatorRequest {
private final int floor;
private final Direction direction;
private final boolean valid;

public ElevatorRequest(String rawInput, int min, int max) {
    String content = rawInput.replaceAll("[<>]", "");
    int tempFloor = -1;
    Direction tempDir = null;
    boolean isValid = false;

    if (content.contains(",")) {
        String[] parts = content.split(",");
        if (parts.length == 2) {
            try {
                int f = Integer.parseInt(parts[0].trim());
                String dir = parts[1].trim();
                if ((dir.equals("UP") || dir.equals("DOWN")) && f >= min && f <= max) {
                    tempFloor = f;
                    tempDir = Direction.valueOf(dir);
                    isValid = true;
                }
            } catch (Exception ignored) {}
        }
    } else {
        try {
            int f = Integer.parseInt(content.trim());
            if (f >= min && f <= max) {
                tempFloor = f;
                isValid = true;
            }
        } catch (Exception ignored) {}
    }

    this.floor = tempFloor;
    this.direction = tempDir;
    this.valid = isValid;
}

public boolean isValid() { return valid; }
public int getFloor() { return floor; }
public Direction getDirection() { return direction; }
public RequestType getType() { return direction == null ? RequestType.INNER : RequestType.OUTER; }

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    ElevatorRequest that = (ElevatorRequest) o;
    return floor == that.floor && direction == that.direction;
}

@Override
public int hashCode() {
    return Objects.hash(floor, direction);
}

}

// 电梯核心类:维护电梯状态
class ElevatorCore {
private int currentLevel;
private Direction movementState;
private final int minLevel;
private final int maxLevel;

public ElevatorCore(int min, int max) {
    this.minLevel = min;
    this.maxLevel = max;
    this.currentLevel = min;
    this.movementState = Direction.IDLE;
}

public void changeDirection(Direction newState) {
    this.movementState = newState;
}

public void ascend() { 
    if (currentLevel < maxLevel) currentLevel++;
}

public void descend() {
    if (currentLevel > minLevel) currentLevel--;
}

public int getCurrentLevel() { return currentLevel; }
public Direction getMovementState() { return movementState; }

}

// 调度算法类:实现LOOK逻辑
class Scheduler {
private final ElevatorCore elevator;
private final RequestManager requests;
private static final int SCAN_INTERVAL = 1;

public Scheduler(ElevatorCore elevator, RequestManager requests) {
    this.elevator = elevator;
    this.requests = requests;
}

public void executeOperations() {
    while (requests.hasPendingRequests()) {
        determineInitialMovement();
        if (elevator.getMovementState() == Direction.IDLE) break;
        
        do {
            moveElevator();
            handleCurrentLevel();
            adjustMovementState();
        } while (shouldContinueMoving());
    }
}

private void determineInitialMovement() {
    int nearest = Integer.MAX_VALUE;
    Direction selectedDir = Direction.IDLE;
    final int current = elevator.getCurrentLevel();

    // 外部上行请求分析
    for (int target : requests.getUpwardCalls()) {
        if (target >= current && target - current < nearest) {
            nearest = target - current;
            selectedDir = Direction.UP;
        }
    }

    // 外部下行请求分析
    for (int target : requests.getDownwardCalls()) {
        if (target <= current && current - target < nearest) {
            nearest = current - target;
            selectedDir = Direction.DOWN;
        }
    }

    // 内部请求分析
    for (int target : requests.getInnerTargets()) {
        int distance = Math.abs(target - current);
        Direction dir = target > current ? Direction.UP : Direction.DOWN;
        if (distance < nearest) {
            nearest = distance;
            selectedDir = dir;
        }
    }

    elevator.changeDirection(selectedDir);
}

private void moveElevator() {
    if (elevator.getMovementState() == Direction.UP) {
        elevator.ascend();
    } else {
        elevator.descend();
    }
    System.out.printf("Current Floor: %d Direction: %s\n", 
        elevator.getCurrentLevel(), elevator.getMovementState());
}

private void handleCurrentLevel() {
    int current = elevator.getCurrentLevel();
    boolean needsStop = false;

    // 处理内部请求
    if (requests.getInnerTargets().contains(current)) {
        requests.clearRequest(current, null);
        needsStop = true;
    }

    // 处理外部请求
    if (elevator.getMovementState() == Direction.UP) {
        if (requests.getUpwardCalls().contains(current)) {
            requests.clearRequest(current, Direction.UP);
            needsStop = true;
        }
    } else {
        if (requests.getDownwardCalls().contains(current)) {
            requests.clearRequest(current, Direction.DOWN);
            needsStop = true;
        }
    }

    if (needsStop) {
        System.out.printf("Open Door # Floor %d\n", current);
        System.out.println("Close Door");
    }
}

private void adjustMovementState() {
    Direction currentDir = elevator.getMovementState();
    if (currentDir == Direction.IDLE) return;

    Set<Integer> targets = currentDir == Direction.UP ? 
        requests.getUpwardCalls() : requests.getDownwardCalls();
    targets.addAll(requests.getInnerTargets());

    boolean hasForwardRequest = targets.stream()
        .anyMatch(f -> currentDir == Direction.UP ? f > elevator.getCurrentLevel() : f < elevator.getCurrentLevel());

    if (!hasForwardRequest) {
        Direction newDir = currentDir == Direction.UP ? Direction.DOWN : Direction.UP;
        elevator.changeDirection(newDir);
    }
}

private boolean shouldContinueMoving() {
    return elevator.getMovementState() != Direction.IDLE && requests.hasPendingRequests();
}

}

enum Direction { UP, DOWN, IDLE }
enum RequestType { INNER, OUTER }`
代码分析:

题目集7:
对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客类、队列类以及控制类,具体设计可参考如下类图。

电梯运行规则与前阶段相同,但有如下变动情况:

乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)
注意:本次作业类设计必须符合如上要求(包含但不限于设计电梯类、乘客类、队列类以及控制类),凡是不符合类设计要求此题不得分,另外,PTA得分代码界定为第一次提交的最高分代码(因此千万不要把第一次及第二次电梯程序提交到本次题目中测试)。

输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。

电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<请求源楼层,请求目的楼层>,其中,请求源楼层表示乘客发起请求所在的楼层,请求目的楼层表示乘客想要到达的楼层。
当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:

运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
输入样例1:
在这里给出一组输入。例如:

1
20
<5,4>
<5>
<7>
end
输出样例1:
在这里给出相应的输出。例如:

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
输入样例2:
在这里给出一组输入。例如:

1
20
<5,9>
<8>
<9,3>
<4>
<2>
end
输出样例2:
在这里给出相应的输出。例如:

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
Open Door # Floor 8
Close Door
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
Current Floor: 4 Direction: DOWN
Open Door # Floor 4
Close Door
Current Floor: 3 Direction: DOWN
Current Floor: 2 Direction: DOWN
Open Door # Floor 2
Close Door
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
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
我的源码:
`import java.util.;
import java.io.
;

enum Direction { UP, DOWN, IDLE }
enum State { MOVING, STOPPED }

class Passenger {
private Integer sourceFloor;
private Integer destinationFloor;

public Passenger() {}
public Passenger(Integer destinationFloor) {
    this.destinationFloor = destinationFloor;
}
public Passenger(Integer sourceFloor, Integer destinationFloor) {
    this.sourceFloor = sourceFloor;
    this.destinationFloor = destinationFloor;
}

public Integer getSourceFloor() { return sourceFloor; }
public Integer getDestinationFloor() { return destinationFloor; }
public Direction getDirection() {
    if (sourceFloor == null || destinationFloor == null || sourceFloor.equals(destinationFloor))
        return Direction.IDLE;
    return destinationFloor > sourceFloor ? Direction.UP : Direction.DOWN;
}

}

class RequestQueue {
private LinkedList internalRequests = new LinkedList<>();
private LinkedList externalRequests = new LinkedList<>();

public static RequestQueue getQueueInstance() { return new RequestQueue(); }
public LinkedList<Passenger> getInternalRequests() { return internalRequests; }
public LinkedList<Passenger> getExternalRequests() { return externalRequests; }
public void addInternalRequest(Passenger p) { internalRequests.add(p); }
public void addExternalRequest(Passenger p) { externalRequests.add(p); }

}

class Elevator {
private int currentFloor;
private Direction direction = Direction.IDLE;
private State state = State.STOPPED;
private final int maxFloor;
private final int minFloor;

public Elevator(int minFloor, int maxFloor) {
    this.minFloor = minFloor;
    this.maxFloor = maxFloor;
    this.currentFloor = minFloor;
}

public int getCurrentFloor() { return currentFloor; }
public void setCurrentFloor(int floor) { currentFloor = floor; }
public Direction getDirection() { return direction; }
public void setDirection(Direction d) { direction = d; }
public State getState() { return state; }
public void setState(State s) { state = s; }
public int getMaxFloor() { return maxFloor; }
public int getMinFloor() { return minFloor; }
public boolean isValidFloor(int floor) { return floor >= minFloor && floor <= maxFloor; }

}

class Controller {
private Elevator elevator;
private RequestQueue queue;

public Controller(Elevator elevator, RequestQueue queue) {
    this.elevator = elevator;
    this.queue = queue;
}

public void processRequests() {
    while (true) {
        determineDirection();
        if (elevator.getDirection() == Direction.IDLE) break;

        int nextFloor = elevator.getCurrentFloor() + (elevator.getDirection() == Direction.UP ? 1 : -1);
        if (!elevator.isValidFloor(nextFloor)) {
            elevator.setDirection(elevator.getDirection() == Direction.UP ? Direction.DOWN : Direction.UP);
            continue;
        }
        elevator.setCurrentFloor(nextFloor);
        System.out.printf("Current Floor: %d Direction: %s%n", elevator.getCurrentFloor(), elevator.getDirection());

        if (shouldStop(elevator.getCurrentFloor())) {
            System.out.printf("Open Door # Floor %d%n", elevator.getCurrentFloor());
            processCurrentFloor(elevator.getCurrentFloor());
            System.out.println("Close Door");
        }
    }
}

private void determineDirection() {
    List<Integer> upRequests = new ArrayList<>();
    List<Integer> downRequests = new ArrayList<>();

    // 收集所有请求
    for (Passenger p : queue.getExternalRequests()) {
        if (p.getSourceFloor() != null) {
            upRequests.add(p.getSourceFloor()); // 外部请求的源楼层总需要处理
        }
    }
    for (Passenger p : queue.getInternalRequests()) {
        if (p.getDestinationFloor() != null) {
            if (p.getDestinationFloor() > elevator.getCurrentFloor()) {
                upRequests.add(p.getDestinationFloor());
            } else {
                downRequests.add(p.getDestinationFloor());
            }
        }
    }

    Direction currentDir = elevator.getDirection();
    int currentFloor = elevator.getCurrentFloor();

    if (currentDir == Direction.UP) {
        if (!upRequests.isEmpty() && Collections.max(upRequests) > currentFloor) {
            elevator.setDirection(Direction.UP);
        } else if (!downRequests.isEmpty()) {
            elevator.setDirection(Direction.DOWN);
        } else {
            elevator.setDirection(Direction.IDLE);
        }
    } else if (currentDir == Direction.DOWN) {
        if (!downRequests.isEmpty() && Collections.min(downRequests) < currentFloor) {
            elevator.setDirection(Direction.DOWN);
        } else if (!upRequests.isEmpty()) {
            elevator.setDirection(Direction.UP);
        } else {
            elevator.setDirection(Direction.IDLE);
        }
    } else {
        // 静止时选择最近的请求方向
        if (!upRequests.isEmpty() || !downRequests.isEmpty()) {
            int closestUp = upRequests.isEmpty() ? Integer.MAX_VALUE : Collections.min(upRequests);
            int closestDown = downRequests.isEmpty() ? Integer.MIN_VALUE : Collections.max(downRequests);
            
            if (currentFloor <= closestUp && currentFloor >= closestDown) {
                elevator.setDirection(
                    (closestUp - currentFloor) <= (currentFloor - closestDown) ? Direction.UP : Direction.DOWN
                );
            } else if (currentFloor <= closestUp) {
                elevator.setDirection(Direction.UP);
            } else {
                elevator.setDirection(Direction.DOWN);
            }
        } else {
            elevator.setDirection(Direction.IDLE);
        }
    }
}

private boolean shouldStop(int floor) {
    // 外部请求:无条件停靠源楼层
    for (Passenger p : queue.getExternalRequests()) {
        if (p.getSourceFloor() != null && p.getSourceFloor() == floor) {
            return true;
        }
    }
    // 内部请求:停靠目的楼层
    for (Passenger p : queue.getInternalRequests()) {
        if (p.getDestinationFloor() != null && p.getDestinationFloor() == floor) {
            return true;
        }
    }
    return false;
}

private void processCurrentFloor(int currentFloor) {
    // 处理外部请求(添加目的楼层到内部队列)
    Iterator<Passenger> extIter = queue.getExternalRequests().iterator();
    while (extIter.hasNext()) {
        Passenger p = extIter.next();
        if (p.getSourceFloor() != null && p.getSourceFloor() == currentFloor) {
            queue.addInternalRequest(new Passenger(p.getDestinationFloor()));
            extIter.remove();
        }
    }
    // 处理内部请求
    Iterator<Passenger> intIter = queue.getInternalRequests().iterator();
    while (intIter.hasNext()) {
        Passenger p = intIter.next();
        if (p.getDestinationFloor() != null && p.getDestinationFloor() == currentFloor) {
            intIter.remove();
        }
    }
}

}

public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int min = Integer.parseInt(br.readLine());
int max = Integer.parseInt(br.readLine());
RequestQueue queue = RequestQueue.getQueueInstance();
String line;
while ((line = br.readLine()) != null) {
line = line.trim().toLowerCase();
if (line.equals("end")) break;
if (line.startsWith("<")) {
String[] parts = line.substring(1, line.length()-1).split(",");
if (parts.length == 1) {
int floor = Integer.parseInt(parts[0].trim());
queue.addInternalRequest(new Passenger(floor));
} else if (parts.length == 2) {
int src = Integer.parseInt(parts[0].trim());
int dest = Integer.parseInt(parts[1].trim());
queue.addExternalRequest(new Passenger(src, dest));
}
}
}
Elevator elevator = new Elevator(min, max);
Controller controller = new Controller(elevator, queue);
controller.processRequests();
}
}`
代码分析:

采坑心得
那就太多坑了,首先是犯了先入为主的错误,明显的按照写C的思想去写题目,没有考虑面对对象的重要性,然后就是对Java的代码使用方法不是很熟练,就导致一直在改代码,还有对于正则表达式的运用实在是不到位。

总结
学习收获:
面向对象能力:类职责划分更加清晰。
算法优化能力:通过实际调试掌握调度算法的权衡与优化技巧。
学习方向:
对于面向对象这一方面的能力,我学多久都不为过,我还是个菜鸟,真的有太多太多不懂的了。

posted on 2025-04-20 23:21  君行一叶舟  阅读(4)  评论(0)    收藏  举报