第一次博客作业

一、前言

第一次博客作业题量适中,电梯迭代作业难度较大,知识点运用较多,如会运用到简易的LOOK算法,会运用到正则表达式,会运用到面向对象中的关联等等。一开始接触到电梯迭代题的时候,我像只无头苍蝇,不知所云,在对难度的恐惧面前,我没有尝试做这个题目。但是后面老师将题目截止时间延长,我决定挑战一下这个题目。通过多次的修改,以及不断的翻阅资料学习,我慢慢地理清了思路,解决了这个题。后面几次作业的要求都是在第一次上面增加,有了第一次的成功,我慢慢地得心应手。以下,我将对此做出分析。

二、设计与分析

1.第一次电梯作业的设计与分析

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

1.2类图:

 

共有四个类:ExternalRequest、InternalRequest、Elevator、Main;

ExternalRequest:用于作为外部队列的类型

InternalRequest:用于作为内部队列的类型

Elevator:用于存放有关电梯的各种方法

Main:用于创建对象以及调用逻辑

 

1.3SourceMonitor分析结果:

 

1.4分析:

代码的复杂度较高:函数的最大复杂度较高,达到了19;函数的平均复杂度也较高,达到了4.18。从中可以看出我的代码设计上有很大的问题,说明我没有遵循单一职责原则,我应当对此进行改进和提升。

代码的平均深度较高:从图中可以看出,我的代码平均深度较高,达到了2.29,这说明我运用了太多的if语句,且分类没有分的很清楚,导致有些语句多余,我应当理清思路,分清楚状况再进行代码的编写。

1.5心得:

注重代码的设计:我应当注重代码的类设计,方法设计,尽最大可能让写出来的程序遵循单一职责原则。在动手前,理清题目意思,弄好代码逻辑设计与方法调用,只有这样,才能减少代码的复杂度。

少用if-else语句:少用点if-else语句,避免代码逻辑混乱,深度较高。

2.第二次电梯电梯作业的设计与分析

2.1题目要求:对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类。

2.2类图:

相较于第一次电梯题目,新增一个类:Controller,用于电梯间的各种控制逻辑调用,而Elevator则用于电梯的各种基本状态

除此之外,新增了许多方法,从而使得processRequests()方法内部更加简洁,用于统筹整个调用逻辑,而move()方法则用于根据电梯运行状态来输出各种提示语句

2.3SourcrMonitor分析结果:

 

2.4分析:

代码最大复杂度较高:由以上图片可知,代码的最大复杂度较高,达到了22,而上次是19,说明我的设计还是有问题。

代码平均复杂度得到了改善:由以上图片可知,代码的平均复杂度得到了良好的改善,第一次是4.18,而这次是2.83。

代码平均深度得到了改善:由以上图片可知,代码的深度较之前更低,达到了2.08,而第一次有2.29。

2.5心得:

尝试降低代码最大复杂度:最大复杂度较高,说明我没有很好地优化代码,我应当重新设计我的代码。

维护代码平均复杂度:平均复杂度降低了,说明我的优化还是有点作用的,只不过得进一步提升。

尽量降低代码的深度:平均深度降低了,说明我将函数拆开也是有点用处的,只不过得进一步提升。

3.第三次电梯作业设计与分析

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

3.2类图:

 相较于第二次迭代,新增一个类Passenger,用于外部请求与内部请求的类型,其中destinationFloor用于存储外部请求的目标楼层

3.3SourceMonitor分析:

 

 

3.4分析:

最大深度减少:通过图片可知,最大深度达到了4,比前两次减少了一些,这说明我的拆分是有用的。

最大复杂度不变:通过图片可知,最大复杂度为22,与上一次相比,保持不变,说明我应当再重新设计下我的代码。

3.5心得:

不要妄想只改一点代码就能降低复杂度等,设计不合理应该重新设计,只有这样才可以有效改变复杂度太高的问题。

写题目的时候不要得过且过,要认真且有毅力一点,不要只想着在原本的代码上加内容而不修改原本代码的不合理之处。

四、踩坑心得

源码:

import java.util.Scanner;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

enum Direction {
    UP,
    DOWN,
    IDLE
}

class ExternalRequest{
    public int floor;
    public Direction direction;

    public ExternalRequest(int floor,Direction direction){
        this.floor = floor;
        this.direction = direction;
    }
}

class InternalRequest{
    public int floor;

    public InternalRequest(int floor){
        this.floor = floor;
    }
}

class Elevator {
    private int minFloor;
    private int maxFloor;
    private Direction currentDirection;
    private int currentFloor;
    private int position;
    Queue<ExternalRequest> externalRequest = new LinkedList<>();
    Queue<InternalRequest> internalRequest = new LinkedList<>();

    public Elevator(int minFloor, int maxFloor ){
        this.minFloor = minFloor;
        this.maxFloor = maxFloor;
        this.currentDirection = Direction.UP;
        this.currentFloor = minFloor-1;
        this.position = currentFloor;
    }

    public void addExternalRequest(int floor,Direction direction){
        externalRequest.add(new ExternalRequest(floor,direction));
    }

    public void addInternalRequest(int floor){
        internalRequest.add(new InternalRequest(floor));
    }

    public void popExternalRequest(){
        externalRequest.poll();
    }

    public void popInternalRequest(){
        internalRequest.poll();
    }

    public Queue getExternalRequests(){
        return externalRequest;
    }

    public Queue getInternalRequests(){
        return internalRequest;
    }

    public void processRequests(){
        position = currentFloor;
        if(currentDirection == Direction.UP){
            int dec = findUpDirectionFloor();
            if(dec == -1){
                change();
            }else{
                currentFloor = dec;
                PutOut2();
                PutOut();
            }
        }else{
            int dec = findDownDirectionFloor();
            if(dec == -1){
                change();
            }else{
                currentFloor = dec;
                PutOut3();
                PutOut();
            }
        }
    }

    public void change(){
        if(currentDirection == Direction.UP)
            currentDirection = Direction.DOWN;
        else
            currentDirection = Direction.UP;
    }

    public void PutOut(){
        System.out.println("Open Door # Floor " + currentFloor);
        System.out.println("Close Door");
    }

    public void PutOut2(){
        while(position < currentFloor){
            position++;
            System.out.println("Current Floor: " + position + " Direction: UP");
        }
    }

    public void PutOut3(){
        while(position > currentFloor){
            position--;
            System.out.println("Current Floor: " + position + " Direction: DOWN");
        }
    }

    public int findUpDirectionFloor(){
        int inF = 50, exF = 50;
        Direction exD = Direction.IDLE;
        if(!internalRequest.isEmpty())
            inF = internalRequest.peek().floor;
        if(!externalRequest.isEmpty()){
            exF = externalRequest.peek().floor;
            exD = externalRequest.peek().direction;
        }
        if(inF == exF && exD == Direction.UP && inF > currentFloor){
            popInternalRequest();
            popExternalRequest();
            return inF;
        }
        if(inF == exF && exD == Direction.DOWN && inF > currentFloor){
            popInternalRequest();
            return inF;
        }
        if(inF < exF && inF > currentFloor){
            popInternalRequest();
            return inF;
        }
        if(exF < inF && exD == Direction.UP && exF > currentFloor){
            popExternalRequest();
            return exF;
        }
        if(inF > currentFloor && !internalRequest.isEmpty()){
            popInternalRequest();
            return inF;
        }
        if(exF == currentFloor){
            popExternalRequest();
            PutOut();
            return -1;
        }
        if(exF > currentFloor && !externalRequest.isEmpty()){
            popExternalRequest();
            currentFloor = exF;
            PutOut2();
            PutOut();
            return -1;
        }
        return -1;
    }

    public int findDownDirectionFloor(){
        int inF = -10, exF = -10;
        Direction exD = Direction.IDLE;
        if(!internalRequest.isEmpty())
            inF = internalRequest.peek().floor;
        if(!externalRequest.isEmpty()){
            exF = externalRequest.peek().floor;
            exD = externalRequest.peek().direction;
        }
        if(inF == exF && exD == Direction.DOWN && inF < currentFloor){
            popInternalRequest();
            popExternalRequest();
            return inF;
        }
        if(inF == exF && exD == Direction.UP && inF < currentFloor){
            popInternalRequest();
            return inF;
        }
        if(inF > exF && inF < currentFloor){
            popInternalRequest();
            return inF;
        }
        if(exF > inF && exD == Direction.DOWN && exF < currentFloor){
            popExternalRequest();
            return exF;
        }
        if(inF < currentFloor && !internalRequest.isEmpty()){
            popInternalRequest();
            return inF;
        }
        if(exF == currentFloor){
            //PutOut2();
            PutOut();
            popExternalRequest();
            return -1;
        }
        if(exF < currentFloor && !externalRequest.isEmpty()){
            currentFloor = exF;
            PutOut3();
            PutOut();
            popExternalRequest();
            return -1;
        }
        return -1;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String data; //输入数据:字符串
        int floor = 0;
        Direction direction = null;
        int minFloor,maxFloor; //电梯最低楼层、最高楼层
        String request = ""; //提取出的乘客请求字符串
        ArrayList<String> list = new ArrayList<>(); //用于接收用户输入的数组
        data = input.next();
        while(!data.equalsIgnoreCase("End")){ //输入以“end”结束
            list.add(data);
            data = input.next();
        }    
        
        minFloor = Integer.parseInt(list.get(0));//第一行,电梯最低楼层
        maxFloor = Integer.parseInt(list.get(1));//第二行,电梯最高楼层
        
        Elevator elevator = new Elevator(minFloor, maxFloor);//创建电梯对象,更改
        
        for(int i = 2; i < list.size(); i++){//从第三行开始为乘客请求
            request = list.get(i);
            if(request.contains(",")){//外部请求
                if (!request.matches("<\\d+,\\s*(UP|DOWN)>")) {
                    System.out.println("Wrong Format");
                }

                String[] parts = request.replaceAll("[<>]", "").split(",");
                floor = Integer.parseInt(parts[0].trim());
                direction = Direction.valueOf(parts[1].trim().toUpperCase());
                elevator.addExternalRequest(floor, direction);//外部请求入队,格式为<楼层数,方向>
            }else{
                if (!request.matches("<\\d+>")) {//内部请求
                    System.out.println("Wrong Format");
                }
                floor = Integer.parseInt(request.replaceAll("[<>]", ""));
                elevator.addInternalRequest(floor);//内部请求入队,格式为<楼层数>
            }
        }
        
         while(!elevator.getInternalRequests().isEmpty()
                 || !elevator.getExternalRequests().isEmpty()){
             elevator.processRequests(); //一次性处理所有的内、外部乘客请求
        }
         
         input.close();
    }
            
}
import java.util.Scanner;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

enum Direction {
    UP,
    DOWN,
    IDLE
}

enum State {
    MOVING,
    STOP
}

class ExternalRequest {
    public int floor;
    public Direction direction;

    public ExternalRequest(int floor, Direction direction) {
        this.floor = floor;
        this.direction = direction;
    }
}

class InternalRequest {
    public int floor;

    public InternalRequest(int floor) {
        this.floor = floor;
    }
}

class Elevator {
    public int currentFloor = 0;
    public Direction direction = Direction.UP;
    public State state = State.MOVING;
    public int maxFloor;
    public int minFloor;

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

    public Elevator getElevatorInstance(int minFloor, int maxFloor) {
        return new Elevator(minFloor, maxFloor);
    }

    public int getCurrentFloor() {
        return currentFloor;
    }

    public void setCurrentFloor(int currentFloor) {
        this.currentFloor = currentFloor;
    }

    public Direction getDirection() {
        return direction;
    }

    public void setDirection(Direction direction) {
        this.direction = direction;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    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;
    private Integer nextFloor = 0;

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

    public Elevator getElevator() {
        return elevator;
    }

    public void setElevator(Elevator elevator) {
        this.elevator = elevator;
    }

    public RequestQueue getQueue() {
        return queue;
    }

    public void setQueue(RequestQueue queue) {
        this.queue = queue;
    }

    public void processRequests() {
        nextFloor = getNextFloor();
        if (nextFloor == -1) {
            determineDirection();
        } else {
            move();
            openDoors();
        }
    }

    private void determineDirection() {
        if (elevator.direction == Direction.UP) {
            elevator.direction = Direction.DOWN;
        } else {
            elevator.direction = Direction.UP;
        }
    }

    private void move() {
        if (elevator.direction == Direction.UP) {
            while (!shouldStop(elevator.currentFloor)) {
                elevator.currentFloor++;
                outPutUp();
            }
        } else {
            while (!shouldStop(elevator.currentFloor)) {
                elevator.currentFloor--;
                outPutDown();
            }
        }
        elevator.currentFloor = nextFloor;
    }

    private void outPutUp() {
        System.out.println("Current Floor: " + elevator.currentFloor + " Direction: UP");
    }

    private void outPutDown() {
        System.out.println("Current Floor: " + elevator.currentFloor + " Direction: DOWN");
    }

    private boolean shouldStop(int floor) {
        return elevator.state == State.MOVING && floor == nextFloor;
    }

    private void judgeVality(){
        if (!queue.internalRequest.isEmpty()) {
            int inF = queue.internalRequest.peek().floor;
            if(!elevator.isValidFloor(inF))
                popInternalRequest();
        }
        if (!queue.externalRequest.isEmpty()) {
            int exF = queue.externalRequest.peek().floor;
            Direction exD = queue.externalRequest.peek().direction;
            if(!elevator.isValidFloor(exF))
                popExternalRequest();
        }
    }
    
    private Integer getNextFloor() {
        judgeVality();
        if (elevator.direction == Direction.UP) {
            return getNextUpFloor();
        } else {
            return getNextDownFloor();
        }
    }

    private Integer getNextUpFloor() {
        int inF = 50, exF = 50;
        Direction exD = Direction.IDLE;
        if (!queue.internalRequest.isEmpty()) {
            inF = queue.internalRequest.peek().floor;
        }
        if (!queue.externalRequest.isEmpty()) {
            exF = queue.externalRequest.peek().floor;
            exD = queue.externalRequest.peek().direction;
        }
        if (inF == exF && exD == Direction.UP && inF > elevator.currentFloor) {
            popInternalRequest();
            popExternalRequest();
            return inF;
        }
        if (inF == exF && exD == Direction.DOWN && inF > elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (inF < exF && inF > elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (exF < inF && exD == Direction.UP && exF > elevator.currentFloor) {
            popExternalRequest();
            return exF;
        }
        if (inF > elevator.currentFloor && !queue.internalRequest.isEmpty()) {
            popInternalRequest();
            return inF;
        }
        if (exF == elevator.currentFloor && exD == Direction.DOWN && !queue.externalRequest.isEmpty()) {
            popExternalRequest();
            return exF;
        }
        if (exF > elevator.currentFloor && exD == Direction.DOWN && !queue.externalRequest.isEmpty()) {
            popExternalRequest();
            return exF;
        }
        return -1;
    }

    private Integer getNextDownFloor() {
        int inF = -10, exF = -10;
        Direction exD = Direction.IDLE;
        if (!queue.internalRequest.isEmpty()) {
            inF = queue.internalRequest.peek().floor;
        }
        if (!queue.externalRequest.isEmpty()) {
            exF = queue.externalRequest.peek().floor;
            exD = queue.externalRequest.peek().direction;
        }
        if (inF == exF && exD == Direction.DOWN && inF < elevator.currentFloor) {
            popInternalRequest();
            popExternalRequest();
            return inF;
        }
        if (inF == exF && exD == Direction.UP && inF < elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (inF > exF && inF < elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (exF > inF && exD == Direction.DOWN && exF < elevator.currentFloor) {
            popExternalRequest();
            return exF;
        }
        if (inF < elevator.currentFloor && !queue.internalRequest.isEmpty()) {
            popInternalRequest();
            return inF;
        }
        if (exF == elevator.currentFloor && !queue.externalRequest.isEmpty() && exD == Direction.UP) {
            popExternalRequest();
            return exF;
        }
        if (exF < elevator.currentFloor && !queue.externalRequest.isEmpty() && exD == Direction.UP) {
            popExternalRequest();
            return exF;
        }
        return -1;
    }

    private Integer getClosetFloor(Integer a, Integer b) {
        return Math.abs(a - elevator.currentFloor) < Math.abs(b - elevator.currentFloor) ? a : b;
    }

    private void openDoors() {
        System.out.println("Open Door # Floor " + nextFloor);
        System.out.println("Close Door");
    }

    private void popExternalRequest() {
        int a = queue.externalRequest.peek().floor;
        Direction exD = queue.externalRequest.peek().direction;
        queue.externalRequest.poll();
        while(!queue.externalRequest.isEmpty()){
            if(a == queue.externalRequest.peek().floor && exD == queue.externalRequest.peek().direction)
                queue.externalRequest.poll();
            else
                break;
        }
    }

    private void popInternalRequest() {
        int a = queue.internalRequest.peek().floor;
        queue.internalRequest.poll();
        while(!queue.internalRequest.isEmpty()){
            if(a == queue.internalRequest.peek().floor)
                queue.internalRequest.poll();
            else
                break;
        }
    }
}

class RequestQueue {
    public Queue<ExternalRequest> externalRequest = new LinkedList<>();
    public Queue<InternalRequest> internalRequest = new LinkedList<>();

    public RequestQueue() {
    }

    public Queue<ExternalRequest> getExternalRequest() {
        return externalRequest;
    }

    public void setExternalRequest(Queue<ExternalRequest> externalRequest) {
        this.externalRequest = externalRequest;
    }

    public Queue<InternalRequest> getInternalRequest() {
        return internalRequest;
    }

    public void setInternalRequest(Queue<InternalRequest> internalRequest) {
        this.internalRequest = internalRequest;
    }

    public void addExternalRequest(int floor, Direction direction) {
        externalRequest.add(new ExternalRequest(floor, direction));
    }

    public void addInternalRequest(int floor) {
        internalRequest.add(new InternalRequest(floor));
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String data; //输入数据:字符串
        int floor = 0;
        Direction direction = null;
        int minFloor,maxFloor; //电梯最低楼层、最高楼层
        String request = ""; //提取出的乘客请求字符串
        ArrayList<String> list = new ArrayList<>(); //用于接收用户输入的数组
        data = input.next();
        while(!data.equalsIgnoreCase("End")){ //输入以“end”结束
            list.add(data);
            data = input.next();
        }

        minFloor = Integer.parseInt(list.get(0));//第一行,电梯最低楼层
        maxFloor = Integer.parseInt(list.get(1));//第二行,电梯最高楼层

        Elevator elevator = new Elevator(minFloor, maxFloor);//创建电梯对象,更改
        RequestQueue requestQueue = new RequestQueue();
        Controller controller = new Controller(elevator,requestQueue);

        for(int i = 2; i < list.size(); i++){//从第三行开始为乘客请求
            request = list.get(i);
            if(request.contains(",")){//外部请求
                if (!request.matches("<\\d+,\\s*(UP|DOWN)>")) {
                    System.out.println("Wrong Format");
                }

                String[] parts = request.replaceAll("[<>]", "").split(",");
                floor = Integer.parseInt(parts[0].trim());
                direction = Direction.valueOf(parts[1].trim().toUpperCase());
                requestQueue.addExternalRequest(floor, direction);//外部请求入队,格式为<楼层数,方向>
            }else{
                if (!request.matches("<\\d+>")) {//内部请求
                    System.out.println("Wrong Format");
                }
                floor = Integer.parseInt(request.replaceAll("[<>]", ""));
                requestQueue.addInternalRequest(floor);//内部请求入队,格式为<楼层数>
            }
        }

        while(!requestQueue.getInternalRequest().isEmpty()
                || !requestQueue.getExternalRequest().isEmpty()){
            controller.processRequests(); //一次性处理所有的内、外部乘客请求
        }

        input.close();
    }

}
import java.util.Scanner;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

enum Direction {
    UP,
    DOWN,
    IDLE
}

class Passenger {
    private Integer sourceFloor = null;
    private Integer destinationFloor = null;

    Passenger() {
    }

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

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

    public Integer getSourceFloor() {
        return sourceFloor;
    }

    public void setSourceFloor(Integer sourceFloor) {
        this.sourceFloor = sourceFloor;
    }

    public Integer getDestinationFloor() {
        return destinationFloor;
    }

    public void setDestinationFloor(Integer destinationFloor) {
        this.destinationFloor = destinationFloor;
    }

    public Direction getDirection() {
        if (destinationFloor < sourceFloor) {
            return Direction.DOWN;
        } else if (destinationFloor > sourceFloor) {
            return Direction.UP;
        }
        return Direction.IDLE;
    }
}

class Elevator {
    public int currentFloor = 0;
    public Direction direction = Direction.UP;
    public int maxFloor;
    public int minFloor;

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

    public Elevator getElevatorInstance(int minFloor, int maxFloor) {
        return new Elevator(minFloor, maxFloor);
    }

    public int getCurrentFloor() {
        return currentFloor;
    }

    public void setCurrentFloor(int currentFloor) {
        this.currentFloor = currentFloor;
    }

    public Direction getDirection() {
        return direction;
    }

    public void setDirection(Direction direction) {
        this.direction = direction;
    }

    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;
    private Integer nextFloor = 0;

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

    public Elevator getElevator() {
        return elevator;
    }

    public void setElevator(Elevator elevator) {
        this.elevator = elevator;
    }

    public RequestQueue getQueue() {
        return queue;
    }

    public void setQueue(RequestQueue queue) {
        this.queue = queue;
    }

    public void processRequests() {
        nextFloor = getNextFloor();
        if (nextFloor == -1) {
            determineDirection();
        } else {
            move();
            openDoors();
        }
    }

    private void determineDirection() {
        if (elevator.direction == Direction.UP) {
            elevator.direction = Direction.DOWN;
        } else {
            elevator.direction = Direction.UP;
        }
    }

    private void move() {
        if (elevator.direction == Direction.UP) {
            while (!shouldStop(elevator.currentFloor)) {
                elevator.currentFloor++;
                outPutUp();
            }
        } else {
            while (!shouldStop(elevator.currentFloor)) {
                elevator.currentFloor--;
                outPutDown();
            }
        }
        elevator.currentFloor = nextFloor;
    }

    private void outPutUp() {
        System.out.println("Current Floor: " + elevator.currentFloor + " Direction: UP");
    }

    private void outPutDown() {
        System.out.println("Current Floor: " + elevator.currentFloor + " Direction: DOWN");
    }

    private boolean shouldStop(int floor) {
        return floor == nextFloor;
    }

    private void judgeValidity() {
        if (!queue.internalRequest.isEmpty()) {
            int inF = queue.internalRequest.peek().getSourceFloor();
            if (!elevator.isValidFloor(inF)) {
                popInternalRequest();
            }
        }
        if (!queue.externalRequest.isEmpty()) {
            int exF = queue.externalRequest.peek().getSourceFloor();
            if (!elevator.isValidFloor(exF)) {
                popExternalRequest();
            }
        }
    }

    private Integer getNextFloor() {
        judgeValidity();
        if (elevator.direction == Direction.UP) {
            return getNextUpFloor();
        } else {
            return getNextDownFloor();
        }
    }

    private Integer getNextUpFloor() {
        int inF = 50, exF = 50;
        int deF = 25;
        Direction exD = Direction.IDLE;
        if (!queue.internalRequest.isEmpty()) {
            inF = queue.internalRequest.peek().getSourceFloor();
        }
        if (!queue.externalRequest.isEmpty()) {
            exF = queue.externalRequest.peek().getSourceFloor();
            deF = queue.externalRequest.peek().getDestinationFloor();
            exD = queue.externalRequest.peek().getDirection();
            //queue.addInternalRequest(deF);
        }
        if (inF == exF && exD == Direction.UP && inF > elevator.currentFloor) {
            popInternalRequest();
            popExternalRequest();
            //queue.addInternalRequest(deF);
            return inF;
        }
        if (inF == exF && exD == Direction.DOWN && inF > elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (inF < exF && inF > elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (exF < inF && exD == Direction.UP && exF > elevator.currentFloor) {
            popExternalRequest();
            queue.addInternalRequest(deF);
            return exF;
        }
        if (inF > elevator.currentFloor && !queue.internalRequest.isEmpty()) {
            popInternalRequest();
            return inF;
        }
        if (exF == elevator.currentFloor && exD == Direction.DOWN && !queue.externalRequest.isEmpty()) {
            popExternalRequest();
            queue.addInternalRequest(deF);
            return exF;
        }
        if (exF > elevator.currentFloor && exD == Direction.DOWN && !queue.externalRequest.isEmpty()) {
            popExternalRequest();
            queue.addInternalRequest(deF);
            return exF;
        }
        return -1;
    }

    private Integer getNextDownFloor() {
        int inF = -10, exF = -10;
        int deF = -25;
        Direction exD = Direction.IDLE;
        if (!queue.internalRequest.isEmpty()) {
            inF = queue.internalRequest.peek().getSourceFloor();
        }
        if (!queue.externalRequest.isEmpty()) {
            exF = queue.externalRequest.peek().getSourceFloor();
            deF = queue.externalRequest.peek().getDestinationFloor();
            exD = queue.externalRequest.peek().getDirection();
        }
        if (inF == exF && exD == Direction.DOWN && inF < elevator.currentFloor) {
            popInternalRequest();
            popExternalRequest();
            //queue.addInternalRequest(deF);
            return inF;
        }
        if (inF == exF && exD == Direction.UP && inF < elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (inF > exF && inF < elevator.currentFloor) {
            popInternalRequest();
            return inF;
        }
        if (exF > inF && exD == Direction.DOWN && exF < elevator.currentFloor) {
            popExternalRequest();
            queue.addInternalRequest(deF);
            return exF;
        }
        if (inF < elevator.currentFloor && !queue.internalRequest.isEmpty()) {
            popInternalRequest();
            return inF;
        }
        if (exF == elevator.currentFloor && !queue.externalRequest.isEmpty() && exD == Direction.UP) {
            popExternalRequest();
            queue.addInternalRequest(deF);
            return exF;
        }
        if (exF < elevator.currentFloor && !queue.externalRequest.isEmpty() && exD == Direction.UP) {
            popExternalRequest();
            queue.addInternalRequest(deF);
            return exF;
        }
        return -1;
    }

    private void openDoors() {
        System.out.println("Open Door # Floor " + nextFloor);
        System.out.println("Close Door");
    }

    private void popExternalRequest() {
        queue.externalRequest.poll();
    }

    private void popInternalRequest() {
        queue.internalRequest.poll();
    }
}

class RequestQueue {
    public Queue<Passenger> externalRequest = new LinkedList<>();
    public Queue<Passenger> internalRequest = new LinkedList<>();

    RequestQueue() {
    }

    public Queue<Passenger> getExternalRequest() {
        return externalRequest;
    }

    public void setExternalRequest(Queue<Passenger> externalRequest) {
        this.externalRequest = externalRequest;
    }

    public Queue<Passenger> getInternalRequest() {
        return internalRequest;
    }

    public void setInternalRequest(Queue<Passenger> internalRequest) {
        this.internalRequest = internalRequest;
    }

    public void addExternalRequest(int sourceFloor, int destinationFloor) {
        externalRequest.add(new Passenger(sourceFloor, destinationFloor));
    }

    public void addInternalRequest(int sourceFloor) {
        internalRequest.add(new Passenger(sourceFloor));
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String data; // 输入数据:字符串
        int sourceFloor = 0;
        int destinationFloor = 0;
        int minFloor, maxFloor; // 电梯最低楼层、最高楼层
        String request = ""; // 提取出的乘客请求字符串
        ArrayList<String> list = new ArrayList<>(); // 用于接收用户输入的数组
        data = input.next();
        while (!data.equalsIgnoreCase("End")) { // 输入以“end”结束
            list.add(data);
            data = input.next();
        }

        minFloor = Integer.parseInt(list.get(0));// 第一行,电梯最低楼层
        maxFloor = Integer.parseInt(list.get(1));// 第二行,电梯最高楼层

        Elevator elevator = new Elevator(minFloor, maxFloor);// 创建电梯对象,更改
        RequestQueue requestQueue = new RequestQueue();
        Controller controller = new Controller(elevator, requestQueue);

        for (int i = 2; i < list.size(); i++) { // 从第三行开始为乘客请求
            request = list.get(i);
            if (request.contains(",")) { // 外部请求
                String[] parts = request.replaceAll("[<>]", "").split(",");
                sourceFloor = Integer.parseInt(parts[0]);
                destinationFloor = Integer.parseInt(parts[1]);
                requestQueue.addExternalRequest(sourceFloor, destinationFloor);
            } else {
                // 内部请求
                sourceFloor = Integer.parseInt(request.replaceAll("[<>]", ""));
                requestQueue.addInternalRequest(sourceFloor);
            }
        }

        while (!requestQueue.getInternalRequest().isEmpty()
                || !requestQueue.getExternalRequest().isEmpty()) {
            controller.processRequests(); // 一次性处理所有的内、外部乘客请求
        }

        input.close();
    }
}
View Code

 

  

1.非零返回:我提交代码时多次出现“非零返回”这个错误,原因是我的代码死循环了,就是我在第二次电梯类设计的时候,移除相同的请求的时候,while循环的判断条件有误,导致了“非零返回”这个错误。

 

 

2.运行空值问题:我有些时候运行的时候会出现空的情况,这个在于我设计的判断条件不合理,在运行的时候出了点问题,所以我应当用一个测试用例,然后进行调试。

3.题意理解偏差:我一开始在写题目的时候,没有理清题目的意思,导致我的思路出现了错误,导致我最后一天慌慌张张地重新写了好几个思路不同的代码。通过这次电梯题目的训练,我懂得了要理清题目的大意再开始写。

 

 

4.知识点不完善:一开始难倒我的是LOOK算法。我不太清楚什么是方向优先,所以一开始就盲目地做,后来在同学的帮助下我逐渐理解了LOOK算法。然后,是正则表达式。一开始我不知道有这个东西的存在,于是我就自己写了几个方法去除无关符号,但是效果不是很好,后来通过学堂在线以及老师发的主源码,我弄清楚了这个,后面就清晰了很多。除此之外,我一开始并不知道是模拟两个队列,取队首元素,我以为是找整个内部和外部请求的最大或最小值,导致逻辑不符合题意。

五、建议

1.了解知识点:在编码前了解清楚相应的知识点,这样编码才不会混乱

2.设计清楚:在编码前将类与类之间的关系,以及方法调用等逻辑设计清楚

3.适当注释:增加编码中的注释,提高代码的可维护性

六、总结

本篇Blog包含了以下内容:对三次题目迭代作业的概述、对三次迭代作业代码的分析、对三次迭代作业的心得以及对老师的建议。

通过此次分析,我明晰了自己的一些问题,比较明显的问题就是我的代码设计。我不太善于设计代码之间的逻辑,导致我代码逻辑混乱。

此次迭代作业历经一个月,我收获了许多,如:LOOK算法的运用、正则表达式的运用、类与类之间关联的运用、怎么设计方法之间的调用逻辑、如何遵循单一职责原则、如何画类图等等。

但也有许多不足,如:多次迭代,我依旧没有设计好代码的深度,也没有有效地降低复杂度等等。

我将在之后的学习中,将收获的东西好好吸收运用,不足的地方再加以改正,争取写出的代码逻辑更好,更加规范。

除此之后,我还应当注重代码的可维护性,多写注释,且是写规范的注释,只有这样,才能写出更好的代码。

建议:

1.减轻压力:希望老师不要给同学们太多的压力,不利于同学们的身心健康。

2.难度递增:我认为题目集的难度应该慢慢地增长,而不是突然之间难度飙升,这样会让同学们失去学编程的信心与兴趣。

3.细致评分:我认为题目给分应当给得更加细致,这样才能够给一些部分正确的同学一些分还有信心。

4.完善测试点:题目通过的测试点好像有些问题,测试点好像没有把各种情况给全,导致一些有问题的代码也能过,而且会导致同学们发现不了自己的一些错误,从而把错误晾在那,错失了纠正错误的好机会。

 

posted @ 2025-04-20 22:00  D_0723  阅读(21)  评论(0)    收藏  举报