第一次Blog作业:电梯调度问题

1. 前言
本次电梯调度问题共分三个题目集,设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
第一次题目集只要求实现简单的调度,只需设计一个电梯类.
第二次题目集要求按类图写,并要遵循单一职责原则.
第三次题目在之前的基础上进行再次改进.
三次电梯类题目迭代,极大提升了我的编程能力。首次实现基本功能,让我掌握基础逻辑;二次按类图分多个类,锻炼了面向对象设计与代码架构能力;三次改进时接触性能优化等,加深对复杂编程问题的理解与处理能力。每一次迭代都是成长,助我在编程路上稳步前行。
2.设计与分析
题目集5
设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求),具体运行规则详见输入输出样例。

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

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

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

1
20
❤️,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
本次题目集不考虑特殊情况,类设计简单

Main
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();
	}
			
}
Direction
enum Direction{
    UP,
    DOWN,
    STAY
}
ExternalRequest
class ExternalRequest{
    public int floor;
    public Direction direction;
    public int getfloor(){
return floor;
    }
    public Direction getdirection(){
        return direction;
    }
    public ExternalRequest(int floor,Direction direction){
    this.floor = floor;
    this.direction = direction;
        }
}
Elevator

class Elevator{
    private int maxFloor,minFloor,newFloor;
    private Direction direction = Direction.UP;
    private LinkedList<Integer> internalRequest;
    private LinkedList<ExternalRequest> externalRequest;
    public Elevator(int minFloor,int maxFloor){
        this.minFloor = minFloor;
        this.maxFloor = maxFloor;
        this.newFloor = 1;
        this.internalRequest = new LinkedList<>();
        this.externalRequest = new LinkedList<>();
    }
    public void addInternalRequest(int floor){
        internalRequest.add(floor);
    }
    public void addExternalRequest(int floor,Direction direction){
        ExternalRequest newexter = new ExternalRequest(floor,direction);
        externalRequest.add(newexter);
    }
    public LinkedList<Integer> getInternalRequests(){
        return internalRequest;
    }
    public LinkedList<ExternalRequest> getExternalRequests(){
        return externalRequest;
    }
    public void processRequests(){
        int infloor = internalRequest.peek();
        ExternalRequest headexrequest = externalRequest.peek();
        int exfloor = headexrequest.floor;
        Direction exdirection = headexrequest.direction;
        System.out.println("Current Floor: 1 Direction: UP");
        while(!getInternalRequests().isEmpty()
				 || !getExternalRequests().isEmpty()){
        while(direction == Direction.UP){
            newFloor++;
            if(infloor == newFloor){
                System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                internalRequest.poll();
                while(!getExternalRequests().isEmpty()&&getInternalRequests().isEmpty()){
                    if(exfloor>newFloor)
                    direction = Direction.UP;
                    else
                    direction = Direction.DOWN;
                    if(direction == Direction.UP)
                        newFloor++;
                    else
                        newFloor--;
System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                    if(newFloor == exfloor){
                        System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                    externalRequest.poll();
                    if(!getExternalRequests().isEmpty()){
                        headexrequest = externalRequest.peek();
                   exfloor = headexrequest.floor;
                  exdirection = headexrequest.direction;
                    }
                        
                        }
                    if(getExternalRequests().isEmpty()&&getInternalRequests().isEmpty())
                        return;
                }
                //if(!getInternalRequests().isEmpty())
                infloor = internalRequest.peek();
                if(isdirection(infloor,exfloor,direction))
                    direction = Direction.UP;
                else
                    direction = Direction.DOWN;
            }
            else
            if(exfloor == newFloor &&exdirection == Direction.UP){
                System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                externalRequest.poll();//删去外部
                while(getExternalRequests().isEmpty()&&!getInternalRequests().isEmpty()){
                    if(infloor>newFloor)
                    direction = Direction.UP;
                    else
                    direction = Direction.DOWN;
                    if(direction == Direction.UP)
                        newFloor++;
                    else
                        newFloor--;
System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                    if(newFloor == infloor){
                        System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                    internalRequest.poll();
                    if(!getInternalRequests().isEmpty()){
                   infloor = internalRequest.peek();
                    }
                        
                        }
                    if(getExternalRequests().isEmpty()&&getInternalRequests().isEmpty())
                        return;
                }
                if(!getExternalRequests().isEmpty()){
                headexrequest = externalRequest.peek();
                exfloor = headexrequest.floor;
                exdirection = headexrequest.direction;}
                if(isdirection(infloor,exfloor,direction))
                    direction = Direction.UP;
                else
                    direction = Direction.DOWN;
            }
                else
                    System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
        }//方向向上
            while(direction == Direction.DOWN){
                newFloor--;
                if(infloor == newFloor){
                System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                internalRequest.poll();
                while(!getExternalRequests().isEmpty()&&getInternalRequests().isEmpty()){
                    if(exfloor>newFloor)
                    direction = Direction.UP;
                    else
                    direction = Direction.DOWN;
                    if(direction == Direction.UP)
                        newFloor++;
                    else
                        newFloor--;
System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                    if(newFloor == exfloor){
                        System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                    externalRequest.poll();
                    if(!getExternalRequests().isEmpty()){
                        headexrequest = externalRequest.peek();
                   exfloor = headexrequest.floor;
                  exdirection = headexrequest.direction;
                    }
                        
                        }
                    if(getExternalRequests().isEmpty()&&getInternalRequests().isEmpty())
                        return;
                }
                //if(!getInternalRequests().isEmpty())
                infloor = internalRequest.peek();
                if(isdirection(infloor,exfloor,direction))
                    direction = Direction.UP;
                else
                    direction = Direction.DOWN;
            }
            else
            if(exfloor == newFloor &&exdirection == Direction.DOWN){
                System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                externalRequest.poll();
                while(getExternalRequests().isEmpty()&&!getInternalRequests().isEmpty()){
                    if(infloor>newFloor)
                    direction = Direction.UP;
                    else
                    direction = Direction.DOWN;
                    if(direction == Direction.UP)
                        newFloor++;
                    else
                        newFloor--;
System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
                    if(newFloor == infloor){
                        System.out.println("Open Door # Floor " + newFloor);
                System.out.println("Close Door");
                    internalRequest.poll();
                    if(!getInternalRequests().isEmpty()){
                   infloor = internalRequest.peek();
                    }
                        
                        }
                    if(getExternalRequests().isEmpty()&&getInternalRequests().isEmpty())
                        return;
                }
                if(!getExternalRequests().isEmpty()){
                headexrequest = externalRequest.peek();
                exfloor = headexrequest.floor;
                exdirection = headexrequest.direction;}
                if(isdirection(infloor,exfloor,direction))
                    direction = Direction.UP;
                else
                    direction = Direction.DOWN;
            }
                else
                    System.out.println("Current Floor: " + newFloor + " Direction: " + direction);
            }//方向向下
            if(getExternalRequests().isEmpty()&&getExternalRequests().isEmpty())
                return;
    }
 }
    public boolean isdirection(int infloor,int exfloor,Direction exdirection){
        if(direction == Direction.UP){
            if(newFloor < infloor||exfloor > newFloor)
                return true;
            else
                return false;
            
        }
        if(direction == Direction.DOWN){
            if(newFloor > infloor||exfloor < newFloor)
                return false;
            else
                return true;
        }
        return true;
    }
    //System.out.println("Current Floor: " + newFloor + "Direction: " + direction);
    //System.out.println("Open Door # Floor " + newFloor);
    //System.out.println("Close Door");
}

Source Monitor分析结果
image
image
image
image
本次题目集写的不是很好,算法和设计都需改进.

题目集六
本次题目集在题目集五的基础上增加了类设计以及去重的要求
代码如下

Main
public class Main{
    public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		String data; //输入数据:字符串
        String previous = null; 
		int floor = 0;
		Direction direction = null;
		int minFloor,maxFloor; //电梯最低楼层、最高楼层
		String request = ""; //提取出的乘客请求字符串
		ArrayList<String> list = new ArrayList<>(); //用于接收用户输入的数组
		data = input.next();
		while(!data.equalsIgnoreCase("End")){ //输入以“end”结束
           if (previous == null || !data.equals(previous)) {
                list.add(data);
                previous = data;
            }
            data = input.next();
		}	
		
		minFloor = Integer.parseInt(list.get(0));//第一行,电梯最低楼层
		maxFloor = Integer.parseInt(list.get(1));//第二行,电梯最高楼层
		
		Elevator elevator = new Elevator(minFloor, maxFloor);//创建电梯对象
		RequestQueue queue = new RequestQueue();
       // Controller controller = new Controller(elevator,queue);
		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());
                if(floor<=maxFloor&&floor>=minFloor)
				queue.addExternalRequests(floor, direction);//外部请求入队,格式为<楼层数,方向>
			}else{
				if (!request.matches("<\\d+>")) {//内部请求
					System.out.println("Wrong Format");
				}
				floor = Integer.parseInt(request.replaceAll("[<>]", ""));
                if(floor<=maxFloor&&floor>=minFloor)
				queue.addInternalRequests(floor);//内部请求入队,格式为<楼层数>
			}
		}
		Controller controller = new Controller(elevator,queue);
		 while(!controller.getQueue().getExternalRequests().isEmpty()||!controller.getQueue().getInternalRequests().isEmpty()){
			 controller.processRequests(); //一次性处理所有的内、外部乘客请求
		}
		 
		 input.close();
	
    }
}
Direction
enum Direction{
    UP,
    DOWN,
    STAY
}
ExternalRequest
class ExternalRequest{
    private int floor;
    private Direction direction;
    public int getfloor(){
return floor;
    }
    public Direction getDirection(){
        return direction;
    }
    public ExternalRequest(int floor,Direction direction){
    this.floor = floor;
    this.direction = direction;
        }
}
RequestQueue
class RequestQueue{
    private LinkedList<Integer> internalRequests;
    private LinkedList<ExternalRequest> externalRequests;
    public RequestQueue() {
        this.internalRequests = new LinkedList<>();
        this.externalRequests = new LinkedList<>();
    }
    public void setInternalRequests(LinkedList<Integer> internalRequests){
        this.internalRequests = internalRequests;
    }
    public LinkedList<Integer> getInternalRequests() {
        return internalRequests;
    }
    public void setExternalRequests(LinkedList<ExternalRequest> externalRequests){
        this.externalRequests = externalRequests;
    }
    public LinkedList<ExternalRequest> getExternalRequests() {
        return externalRequests;
    }
    public void addInternalRequests(int floor){
        internalRequests.add(floor);
    }
    public void addExternalRequests(int floor,Direction direction){
        ExternalRequest newexter = new ExternalRequest(floor,direction);
        externalRequests.add(newexter);
    }
}
Controller

class Controller{
    private Elevator elevator;
    private RequestQueue queue;
    public Controller(Elevator elevator,RequestQueue requestQueue){
        this.elevator = elevator;
        this.queue = requestQueue;
    }
    private void openDoors(){
        System.out.println("Open Door # Floor " + elevator.getCurrentFloor());
        System.out.println("Close Door");
    }
    private void move(){
        if(elevator.getDirection() == Direction.UP){
            elevator.setCurrentFloor(1);
        }
        if(elevator.getDirection() == Direction.DOWN){
            elevator.setCurrentFloor(-1);
        }
        System.out.println("Current Floor: " + elevator.getCurrentFloor() 
          + " Direction: " + elevator.getDirection());
    }
    private void determineDirection(){
        if(queue.getExternalRequests().isEmpty()||queue.getInternalRequests().isEmpty())
            return;
        int infloor = queue.getInternalRequests().peek();
        int exfloor = queue.getExternalRequests().peek().getfloor();
        int newfloor = elevator.getCurrentFloor();
        if(elevator.getDirection() == Direction.UP){
            if(newfloor > infloor&&exfloor < newfloor)
                elevator.setDirection(Direction.DOWN);
            
        }
        if(elevator.getDirection() == Direction.DOWN){
            if(newfloor < infloor&&exfloor > newfloor)
                elevator.setDirection(Direction.UP);
        }
    }
    private boolean shouldStop(){
        int infloor = queue.getInternalRequests().peek();
        int exfloor = queue.getExternalRequests().peek().getfloor();
        int newfloor = elevator.getCurrentFloor();
        Direction exdirection = queue.getExternalRequests().peek().getDirection();
        Direction direction = elevator.getDirection();
        if(newfloor == infloor&&newfloor == exfloor){
            openDoors();
               elevator.direction = queue.getExternalRequests().peek().getDirection();
            queue.getInternalRequests().poll();
            queue.getExternalRequests().poll();
            return true;
        }
        if(newfloor == infloor){
            openDoors();
            queue.getInternalRequests().poll();
            return true;}
        if(newfloor == exfloor){
            if(direction == Direction.UP){
                if(exdirection == Direction.DOWN &&infloor > exfloor)
                    return false;
                else{
                    openDoors();
                    elevator.direction = queue.getExternalRequests().peek().getDirection();
                    queue.getExternalRequests().poll();
                    exfloor = queue.getExternalRequests().peek().getfloor();
                    return true;}
            }
            if(direction == Direction.DOWN){
                if(exdirection == Direction.UP &&infloor < exfloor)
                    return false;
                else{
                    openDoors();
                    elevator.direction = queue.getExternalRequests().peek().getDirection();
                    queue.getExternalRequests().poll();
                    return true;}
            }
        }
        return true;
    }
    public void processRequests(){
        int infloor = queue.getInternalRequests().peek();
        int exfloor = queue.getExternalRequests().peek().getfloor();
        int newfloor = elevator.getCurrentFloor();
        Direction exdirection = queue.getExternalRequests().peek().getDirection();
        Direction direction = elevator.getDirection();
        System.out.println("Current Floor: 1 Direction: UP");
        if(shouldStop()){
                determineDirection();
        }
        while(true){
        while((!queue.getExternalRequests().isEmpty())&&(!queue.getInternalRequests().isEmpty()))
        { infloor = queue.getInternalRequests().peek();
         exfloor = queue.getExternalRequests().peek().getfloor();
         newfloor = elevator.getCurrentFloor();
        //System.out.println("Current Floor: 1 Direction: UP");
        exdirection = queue.getExternalRequests().peek().getDirection();
        direction = elevator.getDirection();
            move();
            newfloor = elevator.getCurrentFloor();
            if(shouldStop())
                determineDirection();
        }newfloor = elevator.getCurrentFloor();
        while(!queue.getExternalRequests().isEmpty()&&queue.getInternalRequests().isEmpty())
        {//infloor = queue.getInternalRequests().peek();
         exfloor = queue.getExternalRequests().peek().getfloor();
         newfloor = elevator.getCurrentFloor();
        //System.out.println("Current Floor: 1 Direction: UP");
        exdirection = queue.getExternalRequests().peek().getDirection();
        direction = elevator.getDirection();
        if(exfloor>elevator.getCurrentFloor())
                    elevator.direction = Direction.UP;
                    else
                    elevator.direction = Direction.DOWN;
            move();
                    if(elevator.getCurrentFloor() == exfloor){
                        System.out.println("Open Door # Floor " + elevator.getCurrentFloor());
                System.out.println("Close Door");
                elevator.direction = queue.getExternalRequests().peek().getDirection();
                    queue.getExternalRequests().poll();
                    if(!queue.getExternalRequests().isEmpty()){
                   exfloor = queue.getExternalRequests().peek().getfloor();
                  exdirection = queue.getExternalRequests().peek().getDirection();
                    }
                        
                        }
                    if(queue.getExternalRequests().isEmpty()&&queue.getInternalRequests().isEmpty())
                        return;
        }
        while(queue.getExternalRequests().isEmpty()&&!queue.getInternalRequests().isEmpty())
        {infloor = queue.getInternalRequests().peek();
         //exfloor = queue.getExternalRequests().peek().getfloor();
         newfloor = elevator.getCurrentFloor();
        //System.out.println("Current Floor: 1 Direction: UP");
        //exdirection = queue.getExternalRequests().peek().getDirection();
        direction = elevator.getDirection();
        if(infloor>newfloor)
                    elevator.direction = Direction.UP;
                    else
                    elevator.direction = Direction.DOWN;
                    move();
            newfloor = elevator.getCurrentFloor();
                    if(newfloor == infloor){
                        System.out.println("Open Door # Floor " + newfloor);
                System.out.println("Close Door");
                    queue.getInternalRequests().poll();
                    if(!queue.getInternalRequests().isEmpty()){
                   infloor = queue.getInternalRequests().peek();
                    }
                        
                        }
                    if(queue.getExternalRequests().isEmpty()&&queue.getInternalRequests().isEmpty())
                        return;
        }
            if(queue.getExternalRequests().isEmpty()&&queue.getInternalRequests().isEmpty())
                        return;
        }
    }
    public RequestQueue getQueue(){
        return queue;
    }
}
Elevator
class Elevator{
    private int currentFloor = 1;
    public Direction direction = Direction.UP;
    private int maxFloor;
    private int minFloor;
    public Elevator( int maxFloor, int minFloor) {
        this.maxFloor = maxFloor;
        this.minFloor = minFloor;
}
    public int getCurrentFloor() {
        return currentFloor;
    }
    public void setCurrentFloor(int currentFloor) {
        this.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;
    }
}

Source Monitor分析结果
image
image
image
image
image
image
总结
本次题目集虽然按照类图进行了设计,但processRequests过于冗长,也不符合单一职责原则,究其原因,设计的不好,进行改错时因未能准确找到错误,一通乱改最后导致processRequests过于冗长.

第七次题目集
对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类
类图
image
代码

Main
public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        String data = null;
        String previous = null;
        String request = " ";
        int floor = 0;
        int destinationFloor = 0;
        int sourceFloor = 0;
        int minFloor,maxFloor;
        ArrayList<String> list = new ArrayList<>();
        data = input.next();
        while(!data.equalsIgnoreCase("End")){
            if(previous == null || !data.equals(previous)){
                list.add(data);
                previous = data;
            }
            data = input.next();
        }
        minFloor = Integer.parseInt(list.get(0));
        maxFloor = Integer.parseInt(list.get(1));
        Elevator elevator = new Elevator(minFloor,maxFloor);
        RequestQueue queue = new RequestQueue();
        for(int i = 2; i < list.size(); i++){
            request = list.get(i);
            if(request.contains(",")){
                if(!request.matches("<\\d+,\\d+>")){
                    System.out.println("Wrong Format");
                    return;
                }
                String[] parts = request.replaceAll("[<>]", "").split(",");
                sourceFloor = Integer.parseInt(parts[0].trim());
                destinationFloor = Integer.parseInt(parts[1].trim());
                if(sourceFloor<=maxFloor&&sourceFloor>=minFloor&&destinationFloor<=maxFloor&&destinationFloor>=minFloor){
                Passenger expassenger = new Passenger(sourceFloor,destinationFloor);
                queue.addExternalRequests(expassenger);
                }
            }else{
                if(!request.matches("<\\d+>")) {
                    System.out.println("Wrong Format");
                    return;
                }
                floor = Integer.parseInt(request.replaceAll("[<>]", ""));
                if(floor<=maxFloor&&floor>=minFloor){
                    Passenger inpassenger = new Passenger(floor);
                    queue.addInternalRequests(inpassenger);
                }
            }
        }
        //Passenger expassenger1 = new Passenger(1,1);
          //      queue.addExternalRequests(expassenger1);
        //System.out.println("1");
        Controller controller = new Controller(elevator,queue);
        
        //queue.getExternalRequests().poll();
        while(!controller.getQueue().getInternalRequests().isEmpty()||!controller.getQueue().getExternalRequests().isEmpty()){
            controller.processRequests();
            //System.out.println("1");
        }
        
        input.close();
    }
}
Direction
enum Direction{
    UP,
    DOWN,
    IDLE
}
State
enum State {
    MOVING,
    STOPPED
}
Passenger

class Passenger{
    private Integer sourceFloor = null;
    private Integer destinationFloor = null;
    public Passenger(Integer sourceFloor,Integer destinationFloor){
        this.sourceFloor = sourceFloor;
        this.destinationFloor = destinationFloor;
    }
    public Passenger(Integer destinationFloor){
        this.destinationFloor = destinationFloor;
    }
    public Passenger(){
    }
    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(sourceFloor < destinationFloor)
            return Direction.UP;
        if(sourceFloor > destinationFloor)
            return Direction.DOWN;
        return Direction.IDLE;
}
}
Elevator

class Elevator{
    private int currentFloor = 1;
    public Direction direction = Direction.UP;
    private int maxFloor;
    private int minFloor;
    private State state = State.MOVING;
    public Elevator( int maxFloor, int minFloor) {
        this.maxFloor = maxFloor;
        this.minFloor = minFloor;
}
    public int getCurrentFloor() {
        return currentFloor;
    }
    public void setCurrentFloor(int currentFloor) {
        this.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 State getState(){
        return state;
    }
    public void setState(State state){
        this.state = state;
}
}
RequestQueue

class RequestQueue{
        private LinkedList<Passenger> internalRequests;
    private LinkedList<Passenger> externalRequests;
    public RequestQueue() {
        this.internalRequests = new LinkedList<>();
        this.externalRequests = new LinkedList<>();
    }
    public void setInternalRequests(LinkedList<Passenger> internalRequests){
        this.internalRequests = internalRequests;
    }
    public LinkedList<Passenger> getInternalRequests() {
        return internalRequests;
    }
    public void setExternalRequests(LinkedList<Passenger> externalRequests){
        this.externalRequests = externalRequests;
    }
    public LinkedList<Passenger> getExternalRequests() {
        return externalRequests;
    }
    public void addInternalRequests(Passenger inpassenger){
        internalRequests.add(inpassenger);
    }
    public void addExternalRequests(Passenger expassenger){
        externalRequests.add(expassenger);
    }
}
Controller
class Controller{
    private Elevator elevator;
    private RequestQueue queue;
    public Controller(Elevator elevator,RequestQueue requestQueue){
        this.elevator = elevator;
        this.queue = requestQueue;
    }
    public Controller() {
        this.elevator = null;
        this.queue = null;
    }
    public Elevator getElevator(){
        return elevator;
    }
    public void setElevator(){
        this.elevator = elevator;
    }
    public RequestQueue getQueue() {
        return queue;
    }
    public void setQueue(RequestQueue queue) {
        this.queue = queue;
    }
    private void openDoors(){
        System.out.println("Open Door # Floor " + elevator.getCurrentFloor());
        System.out.println("Close Door");
    }
    public void removeRequests(int currentFloor){
        int t = 0;
        int x = 0;
        if(!queue.getInternalRequests().isEmpty()){
        if(queue.getInternalRequests().peek().getDestinationFloor() == currentFloor){
            queue.getInternalRequests().poll();
            if(elevator.getDirection()!=Direction.IDLE)
            openDoors();
            t = 1;
        }
        }
        if(!queue.getExternalRequests().isEmpty() && queue.getExternalRequests().peek().getSourceFloor() == currentFloor){
            if(!queue.getInternalRequests().isEmpty()){
                if(elevator.getDirection() == Direction.UP){
                    if(queue.getExternalRequests().peek().getDirection() == Direction.DOWN&&queue.getInternalRequests().peek().getDestinationFloor()>elevator.getCurrentFloor())
                        return;
                }
                if(elevator.getDirection() == Direction.DOWN){
                    if(queue.getExternalRequests().peek().getDirection() == Direction.UP&&queue.getInternalRequests().peek().getDestinationFloor()<elevator.getCurrentFloor())
                        return;
                }
            }
            //if(queue.getInternalRequests().isEmpty())
            //if(queue.getInternalRequests().isEmpty() || queue.getExternalRequests().peek().getDirection() == elevator.getDirection())
                 
                Passenger inpassenger = new Passenger(queue.getExternalRequests().peek().getDestinationFloor());
                queue.addInternalRequests(inpassenger);
                elevator.setDirection(queue.getExternalRequests().peek().getDirection());
                queue.getExternalRequests().poll();
                     //openDoors();
                x = 1;
            
    }
        //if(t==0&&x==1)
            //openDoors();
        if(t==0&&x==1&&elevator.getDirection()!=Direction.IDLE)
            openDoors();
}
    public boolean shouldStop(int floor){
        if(!queue.getInternalRequests().isEmpty()){
            if(queue.getInternalRequests().peek().getDestinationFloor() == floor){
                return true;
            }
            }
        if(!queue.getExternalRequests().isEmpty()){
            if(queue.getExternalRequests().peek().getSourceFloor() == floor)
                return true;
        }
        return false;
    }
    public void move(){
        if(elevator.getDirection() == Direction.IDLE)
            return;
        if(elevator.getDirection() == Direction.UP)
            elevator.setCurrentFloor(1);
        if(elevator.getDirection() == Direction.DOWN)
            elevator.setCurrentFloor(-1);
        System.out.println("Current Floor: " + elevator.getCurrentFloor() +
           " Direction: " + elevator.getDirection());
    }
    public void determineDirection(){
        if(!queue.getInternalRequests().isEmpty()&&!queue.getExternalRequests().isEmpty()){
        if(elevator.getDirection() == Direction.UP){
            if(queue.getInternalRequests().peek().getDestinationFloor() < elevator.getCurrentFloor()&&queue.getExternalRequests().peek().getSourceFloor() < elevator.getCurrentFloor()){
                elevator.setDirection(Direction.DOWN);
                return;
            }
                
        }
        if(elevator.getDirection() == Direction.DOWN){
            if(queue.getInternalRequests().peek().getDestinationFloor() > elevator.getCurrentFloor()&&queue.getExternalRequests().peek().getSourceFloor() > elevator.getCurrentFloor()){
                elevator.setDirection(Direction.UP);
                return;
            }
                
        }
        }
        if(queue.getInternalRequests().isEmpty()&&!queue.getExternalRequests().isEmpty()){
            if(queue.getExternalRequests().peek().getSourceFloor() > elevator.getCurrentFloor())
                elevator.setDirection(Direction.UP);
            if(queue.getExternalRequests().peek().getSourceFloor() < elevator.getCurrentFloor())
                elevator.setDirection(Direction.DOWN);
            if(queue.getExternalRequests().peek().getSourceFloor() == elevator.getCurrentFloor())
                elevator.setDirection(Direction.IDLE);
        }
        if(!queue.getInternalRequests().isEmpty()&&queue.getExternalRequests().isEmpty()){
            if(queue.getInternalRequests().peek().getDestinationFloor() > elevator.getCurrentFloor())
                elevator.setDirection(Direction.UP);
            if(queue.getInternalRequests().peek().getDestinationFloor() < elevator.getCurrentFloor())
                elevator.setDirection(Direction.DOWN);
            if(queue.getInternalRequests().peek().getDestinationFloor() == elevator.getCurrentFloor())
                elevator.setDirection(Direction.IDLE);
        }
}
    public void processRequests(){
        System.out.println("Current Floor: 1 Direction: UP");
            determineDirection();
        while(!queue.getExternalRequests().isEmpty()||!queue.getInternalRequests().isEmpty()){
            move();
            if(shouldStop(elevator.getCurrentFloor()))
                removeRequests(elevator.getCurrentFloor());
                determineDirection();
        }
    }
}

Source Monitor分析结果
image
image
image
image
image
image

总结
本次代码较之前有所改进,类设计更为合理,但最大复杂度仍有19,还需改进.
心得
通过这三次迭代,编程能力有所提高,对类设计所要遵循的原则也有了进一步的认识,虽然对自己在这三次题目集写的代码不太满意,但对于在完成这三次题目集中的收获,我还是挺满意的.在接下来的学习中我要加入Source Monitor的使用,来提高自己的代码质量,而不是仅仅完成任务.

posted on 2025-04-20 21:31  古人类  阅读(10)  评论(0)    收藏  举报