第一次Blog作业:Java电梯调度分析

第一次Blog作业:Java电梯调度分析

一、前言

本学期已经学习Java一个月左右了,刚开始时本人认为Java学习难度并不算太大基础语法只是C语言的变形,相较于C语言反而有更加丰富的类库去方便我们的编写,也一直是以C语言的思想去实现编程,直到PTA作业的题目电梯调度问题。
本次PTA作业分为三次,三次的难度几乎都是一样的,可能是为了让我们从C语言转变为Java语言吧,第一次的难度是最大的需要将电梯的运行逻辑搞明白,而第二、三次都是添加了一些要求也就是对第一次的代码进行迭代并用Java的类的特性也就是封装来完成,如果能够将第一次的题目写出来剩下的两次题目集可能会更快的完成,但三次题目的要求是层序渐进的,这三次题目逐渐让我从C语言的逻辑转换为Java的逻辑,并且刚开始C语言的逻辑让我踩了个大坑这个后续再讲,以下是对三次PTA作业的概要分析。

二、设计与分析

PTA第一次电梯

类图:

代码分析图:

这一次作业也是最让我后悔的一次,看类图就知道C语言的想法还没有转变过来仅有一个电梯类(甚至当时要不是要求必须要有电梯类可能电梯类也不会写)甚至方法也只有三个,简单介绍一下这三个方法,第一个upordown和第二个isopen都是控制输出的,电梯运行的逻辑全部都写在了look里导致代码逻辑及其繁琐甚至我自己都不知道是逻辑是怎么实现的(其实是找对的同学的代码看我和他的同一个测试用例哪里开始输出结果不同调试出来的)。
那就上代码介绍一下吧

点击查看代码
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

class Elevator {
    private int maxfloor;
    private int minfloor;
    private int nowfloor = 1;
    private boolean[] directionpe;
    private boolean direction = true;
    private boolean state = false;
    private int[] inperson;
    private int[] outperson;
    private int[] weizhi;
    private int in = 0;
    private int out = 0;

    public Elevator(int maxfloor, int minfloor, boolean directionpe[], int[] inperson, int[] outperson, int[] weizhi) {
        this.maxfloor = maxfloor;
        this.minfloor = minfloor;
        this.directionpe = directionpe;
        this.inperson = inperson;
        this.outperson = outperson;
        this.weizhi = weizhi;
        while (inperson[this.in] != 0 || outperson[out] != 0) {
            look(in, out, direction, nowfloor, inperson, outperson, directionpe);
        }
    }

    public void upordown(boolean direction, int nowfloor) {
        if (direction) {
            System.out.printf("Current Floor: %d Direction: UP\n", nowfloor);
        } else {
            System.out.printf("Current Floor: %d Direction: DOWN\n", nowfloor);
        }
    }

    public void isopen(int nowfloor) {
        System.out.printf("Open Door # Floor %d\n" + "Close Door\n", nowfloor);
    }

    public void look(int in, int out, boolean direction, int nowfloor, int[] inperson, int[] outperson, boolean[] directionpe) {
        if (inperson[this.in] != 0 && outperson[this.out] != 0) {
            if (direction && directionpe[weizhi[this.out]]) {
                int need = Math.min(inperson[this.in], outperson[this.out]);
                int q = 0;
                if(outperson[this.out]<nowfloor){
                    need = inperson[this.in];
                    q=1;

                }
                if (inperson[this.in] > outperson[this.out]) {
                    this.out++;
                } else {
                    this.in++;
                }
                while (this.nowfloor < need) {
                    upordown(direction, this.nowfloor);
                    this.nowfloor++;
                }
                upordown(direction, this.nowfloor);
                isopen(this.nowfloor);
                if(this.nowfloor == outperson[this.out]) {
                    this.out++;
                }
                if(this.nowfloor == inperson[this.in]) {
                    this.in++;
                }
                this.nowfloor++;
                if(q==1){
                    this.out--;
                }
                if ((this.nowfloor-1 > inperson[this.in] && directionpe[weizhi[this.out]])) {
                    this.direction = false;
                    this.nowfloor -= 2;
                }
            } else if (!(direction || directionpe[weizhi[this.out]])) {
                int need = Math.max(inperson[this.in], outperson[this.out]);
                int q = 0;
                if(outperson[this.out]>nowfloor){
                    need = inperson[this.in];
                    q=1;
                }
                if (inperson[this.in] < outperson[this.out]) {
                    this.out++;
                } else {
                    this.in++;
                }
                while (this.nowfloor > need) {
                    upordown(direction, this.nowfloor);
                    this.nowfloor--;
                }
                upordown(direction, this.nowfloor);
                isopen(this.nowfloor);
                if(this.nowfloor == outperson[this.out]) {
                    this.out++;
                }
                if(this.nowfloor == inperson[this.in]) {
                    this.in++;
                }
                this.nowfloor--;
                if(q==1){
                    this.out--;
                }
                if ((this.nowfloor+1 < inperson[this.in] && !directionpe[weizhi[this.out]])||inperson[this.in]==0) {
                    this.direction = true;
                    this.nowfloor += 2;
                }
            } else if (direction || directionpe[weizhi[this.out]]) {
                int need = inperson[this.in];
                if (direction) {
                    while (this.nowfloor < need) {
                        upordown(direction, this.nowfloor);
                        this.nowfloor++;
                    }
                    upordown(direction, this.nowfloor);
                    isopen(this.nowfloor);
                    if(this.nowfloor == outperson[this.out]) {
                        this.out++;
                    }
                    if(this.nowfloor == inperson[this.in]) {
                        this.in++;
                    }
                    this.nowfloor++;
                    if (this.nowfloor-1 > inperson[this.in ] && !directionpe[weizhi[this.out]]) {
                        this.direction = false;
                        this.nowfloor -= 2;
                    }
                } else {
                    while (this.nowfloor > need) {
                        upordown(direction, this.nowfloor);
                        this.nowfloor--;
                    }
                    upordown(direction, this.nowfloor);
                    isopen(this.nowfloor);
                    if(this.nowfloor == outperson[this.out]) {
                        this.out++;
                    }
                    if(this.nowfloor == inperson[this.in]) {
                        this.in++;
                    }
                    this.nowfloor--;
                    if (this.nowfloor+1 < inperson[this.in ] && directionpe[weizhi[this.out]]) {
                        this.direction = true;
                        this.nowfloor += 2;
                    }
                }
            }
        } else if (inperson[this.in] == 0) {
            int need = outperson[this.out];
            if (this.nowfloor < need) {
                this.direction = true;
            } else {
                this.direction = false;
            }
            this.out++;
            if (this.direction) {
                while (this.nowfloor < need) {
                    upordown(this.direction, this.nowfloor);
                    this.nowfloor++;
                }
                upordown(this.direction, this.nowfloor);
                isopen(this.nowfloor);
                if(this.nowfloor > outperson[this.out]) {
                    this.nowfloor --;
                }else{
                    this.nowfloor ++;
                }
            } else {
                while (this.nowfloor > need) {
                    upordown(this.direction, this.nowfloor);
                    this.nowfloor--;
                }
                upordown(this.direction, this.nowfloor);
                isopen(this.nowfloor);
                if(this.nowfloor > outperson[this.out]) {
                    this.nowfloor --;
                }else{
                    this.nowfloor ++;
                }
            }
        } else {
            int need = inperson[this.in];
            if (this.nowfloor < need) {
                this.direction = true;
            } else {
                this.direction = false;
            }
            this.in++;
            if (this.direction) {
                while (this.nowfloor < need) {
                    upordown(this.direction, this.nowfloor);
                    this.nowfloor++;
                }
                upordown(this.direction, this.nowfloor);
                isopen(this.nowfloor);
                if(this.nowfloor > outperson[this.out]) {
                    this.nowfloor --;
                }else{
                    this.nowfloor ++;
                }
            } else {
                while (this.nowfloor > need) {
                    upordown(this.direction, this.nowfloor);
                    this.nowfloor--;
                }
                upordown(this.direction, this.nowfloor);
                isopen(this.nowfloor);
                if(this.nowfloor > outperson[this.out]) {
                    this.nowfloor --;
                }else{
                    this.nowfloor ++;
                }
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int minfloor = scan.nextInt();
        int maxfloor = scan.nextInt();
        scan.nextLine();
        String[] inperson = new String[1000];
        String[] outperson = new String[1000];
        boolean[] direction = new boolean[1000];
        boolean[] direction1 = new boolean[1000];
        int[] weizhi = new int[1000];
        int incount = 0;
        int outcount = 0;
        String regex1 = "\\d+";
        String regex2 = "[A-Z]+";
        String regex3 = "UP"; // 新增对UP的正则匹配
        Pattern pattern1 = Pattern.compile(regex1);
        Pattern pattern2 = Pattern.compile(regex2);
        Pattern pattern3 = Pattern.compile(regex3);

        while (true) {
            String person = scan.nextLine();
            if (person.equalsIgnoreCase("END")) {
                break;
            }
            Matcher matcher1 = pattern1.matcher(person);
            Matcher matcher2 = pattern2.matcher(person);
            Matcher matcher3 = pattern3.matcher(person);

            if (matcher1.find()) {
                inperson[incount] = matcher1.group();
                incount++;
            }
            if (matcher2.find()) {
                direction[incount - 1] = true;
                weizhi[outcount] = incount - 1;
                outcount++;
            }
            if (matcher3.find()) {
                direction1[incount - 1] = true;
            }
        }
        int[] inPerson = new int[incount - outcount+1];
        int[] outPerson = new int[outcount+1];
        int t = 0;
        int p = 0;
        for (int i = 0; i < incount; i++) {
            int floor = Integer.parseInt(inperson[i]);
            if(floor > maxfloor || floor < minfloor) {
                continue;
            }
            if (direction[i]) {
                outPerson[p] = floor;
                p++;
                continue;
            }
            inPerson[t] = floor;
            t++;
        }
        Elevator elevator = new Elevator(maxfloor, minfloor, direction1, inPerson, outPerson, weizhi);
    }
}
怎么看这代码写的都很史了,但当时就想着这次过了就行也就为我下一次题目埋下了一个大坑,首先主方法里我先用正则表达式将读取的数据分为内部数组和外部数组(当时虽然会用队列但不是很熟悉就用的数组)并将每一个外部的方向记录下来,定义了一个数组用来存每一个外部数组在原本数据中的位置,isopen和upordown都是输出方法不必在意,然后就到了最让我头疼的look了我的电梯逻辑为

1.判断电梯当前运行方向与下一个外部请求方向的关系
2.判断电梯当前情况下应该去外部还是内部请求并将相应数组计数器位置增加
3.判断电梯是否转向
就是这三步让我调试了一天一夜才修改完逻辑当时人都是麻的(但好歹是调出来了)也没管后续逻辑对没对上反正是过了就没管了,结果第二次。。。

PTA第二次电梯

类图:
代码分析图:

看类图就可以知道我多想打死上一次题目集的自己了基本上全部的重构了一遍(本来是想要在原本的上面改的但后来发现难度不下于重新写一遍于是就用着上一次的逻辑又重构了一遍)这一次也是实现了单一职责原则唯一的问题就是电梯的运行逻辑还是写在了一个方法里(实际上在没过的代码中有一份把他拆开的但当时也没过我也不好看就改回去了)
话不多说上代码:

点击查看代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

class Elevator {
    private int maxFloor;
    private int minFloor;
    private int nowFloor = 1;
    private boolean state = false;
    private boolean direction = true;

    public Elevator(int maxFloor, int minFloor) {
        setMaxFloor(maxFloor);
        setMinFloor(minFloor);
    }

    public void setMaxFloor(int maxFloor) {
        this.maxFloor = maxFloor;
    }
    public void setMinFloor(int minFloor) {
        this.minFloor = minFloor;
    }
    public int getMaxFloor() {
        return maxFloor;
    }
    public int getMinFloor() {
        return minFloor;
    }
    public int getNowFloor() {
        return nowFloor;
    }
    public boolean upOrDown() {
        return direction;
    }
    public void setDirection(boolean direction) {
        this.direction = direction;
    }
    public void setState(boolean state) {
        this.state = state;
    }
    public void setNowFloor(int nowFloor) {
        this.nowFloor = nowFloor;
    }
}
class RequestQueue{
    private List<Integer> internalRequests;
    private ExternalRequests externalRequests;
    public RequestQueue(List<Integer> internalRequests, ExternalRequests externalRequests) {
        setInternalRequests(internalRequests);
        setExternalRequests(externalRequests);
    }

    public List<Integer> getInternalRequests() {
        return internalRequests;
    }
    public ExternalRequests getExternalRequests() {
        return externalRequests;
    }
    public void setInternalRequests(List<Integer> internalRequests) {
        this.internalRequests = internalRequests;
    }
    public void setExternalRequests(ExternalRequests externalRequests) {
        this.externalRequests = externalRequests;
    }
}

class ExternalRequests{
    private List<Integer> externalRequests;
    private List<Boolean> direction;
    ExternalRequests(List<Integer> externalRequests, List<Boolean> direction) {
        setExternalRequests(externalRequests);
        setDirection(direction);
    }
    public List<Integer> getExternalRequests() {
        return externalRequests;
    }
    public List<Boolean> getDirection() {
        return direction;
    }
    public void setExternalRequests(List<Integer> externalRequests) {
        this.externalRequests = externalRequests;
    }
    public void setDirection(List<Boolean> direction) {
        this.direction = direction;
    }
}

class Controller{
    private Elevator elevator;
    private RequestQueue requestQueue;
    public Controller(Elevator elevator, RequestQueue requestQueue) {
        setElevator(elevator);
        setRequestQueue(requestQueue);
        while (true) {
            needFloor();
        }
    }
    public Elevator getElevator() {
        return elevator;
    }
    public RequestQueue getRequestQueue() {
        return requestQueue;
    }
    public void setElevator(Elevator elevator) {
        this.elevator = elevator;
    }
    public void setRequestQueue(RequestQueue requestQueue) {
        this.requestQueue = requestQueue;
    }
    public void needFloor() {
        int nowFloor = elevator.getNowFloor();
        int needFloor = 0;
        boolean direction = elevator.upOrDown();
        List<Integer> internalRequests = requestQueue.getInternalRequests();
        ExternalRequests external = requestQueue.getExternalRequests();
        List<Integer> externalRequests = external.getExternalRequests();
        List<Boolean> externalDirections = external.getDirection();
        int exNeedFloor = externalRequests.get(0);
        int inNeedFloor = internalRequests.get(0);
        int nextNeedFloor = internalRequests.get(1);
        boolean direction1 = externalDirections.get(0);
        boolean direction2 = externalDirections.get(1);
        if(inNeedFloor==0&&exNeedFloor==0) {
            System.exit(0);
        }
        if (inNeedFloor!=0&&exNeedFloor!=0) {
            if(direction && direction1){
                if(nowFloor<inNeedFloor&&nowFloor<exNeedFloor) {
                    needFloor = Math.min(exNeedFloor, inNeedFloor);
                    if (inNeedFloor > exNeedFloor) {
                        externalRequests.remove(0);
                        externalDirections.remove(0);
                        external.setDirection(externalDirections);
                        external.setExternalRequests(externalRequests);
                    } else {
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                    }
                    move(needFloor);
                }else if(nowFloor<inNeedFloor&&nowFloor>exNeedFloor) {
                    needFloor = inNeedFloor;
                    internalRequests.remove(0);
                    requestQueue.setInternalRequests(internalRequests);
                    move(needFloor);
                }else if(nowFloor<exNeedFloor&&nowFloor>inNeedFloor) {
                    needFloor = exNeedFloor;
                    externalRequests.remove(0);
                    externalDirections.remove(0);
                    external.setDirection(externalDirections);
                    external.setExternalRequests(externalRequests);
                    move(needFloor);
                }else if(nowFloor>exNeedFloor&&nowFloor>inNeedFloor) {
                    direction=false;
                    elevator.setDirection(direction);
                }
            }else if(!(direction || direction1)){
                if(nowFloor>inNeedFloor&&nowFloor>exNeedFloor) {
                    needFloor = Math.max(exNeedFloor, inNeedFloor);
                    if (inNeedFloor < exNeedFloor) {
                        externalRequests.remove(0);
                        externalDirections.remove(0);
                        external.setDirection(externalDirections);
                        external.setExternalRequests(externalRequests);
                    } else {
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                    }
                    move(needFloor);
                }else if(nowFloor<inNeedFloor&&nowFloor>exNeedFloor) {
                    needFloor = exNeedFloor;
                    externalRequests.remove(0);
                    externalDirections.remove(0);
                    external.setDirection(externalDirections);
                    external.setExternalRequests(externalRequests);
                    internalRequests.remove(0);
                    requestQueue.setInternalRequests(internalRequests);
                    move(needFloor);
                }else if(nowFloor<exNeedFloor&&nowFloor>inNeedFloor) {
                    needFloor = inNeedFloor;
                    internalRequests.remove(0);
                    requestQueue.setInternalRequests(internalRequests);
                    move(needFloor);
                }else if(nowFloor<exNeedFloor&&nowFloor<inNeedFloor) {
                    direction=true;
                    elevator.setDirection(direction);
                }
            }else if(direction||direction1){
                if(direction){
                    if(nowFloor<inNeedFloor) {
                        needFloor = inNeedFloor;
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                        move(needFloor);
                        if (needFloor > nextNeedFloor && !direction1) {
                            direction = false;
                            elevator.setDirection(direction);
                        }
                    }else if(nowFloor>inNeedFloor) {
                        direction = false;
                        elevator.setDirection(direction);
                    }
                }else{
                    if(nowFloor>inNeedFloor) {
                        needFloor = inNeedFloor;
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                        move(needFloor);
                        if (needFloor < nextNeedFloor && direction1) {
                            direction = true;
                            elevator.setDirection(direction);
                        }
                    }else if(nowFloor<inNeedFloor) {
                        direction = true;
                        elevator.setDirection(direction);
                    }
                }
            }
        }else if(inNeedFloor==0){
            needFloor=externalRequests.get(0);
            externalRequests.remove(0);
            external.setExternalRequests(externalRequests);
            if(nowFloor < needFloor) {
                direction = true;
                elevator.setDirection(direction);
            }else{
                direction = false;
                elevator.setDirection(direction);
            }
            move(needFloor);
        }else if(exNeedFloor==0){
            needFloor=internalRequests.get(0);
            internalRequests.remove(0);
            requestQueue.setInternalRequests(internalRequests);
            if(nowFloor < needFloor) {
                direction = true;
                elevator.setDirection(direction);
            }else{
                direction = false;
                elevator.setDirection(direction);
            }
            move(needFloor);
        }
    }

    public void move(int needFloor) {
        boolean direction = elevator.upOrDown();
        while (elevator.getNowFloor() != needFloor) {
            if (direction) {
                elevator.setNowFloor(elevator.getNowFloor() + 1);
                System.out.printf("Current Floor: %d Direction: UP\n", elevator.getNowFloor());
            } else {
                elevator.setNowFloor(elevator.getNowFloor() - 1);
                System.out.printf("Current Floor: %d Direction: DOWN\n", elevator.getNowFloor());
            }
        }
        System.out.printf("Open Door # Floor %d\nClose Door\n", needFloor, needFloor);
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int minfloor = scan.nextInt();
        int maxfloor = scan.nextInt();
        scan.nextLine();
        List<String> stinginternalRequests = new LinkedList<>();
        List<String> stringexternalRequests = new LinkedList<>();
        List<Boolean> direction = new LinkedList<>();
        while (true) {
            String person = scan.nextLine();
            if (person.equalsIgnoreCase("END")) {
                break;
            }
            boolean hasDigit = false;
            boolean hasLetter = false;
            boolean isUp = false;
            StringBuilder digitBuilder = new StringBuilder();
            for (int i = 0; i < person.length(); i++) {
                char c = person.charAt(i);
                if (Character.isDigit(c)) {
                    hasDigit = true;
                    digitBuilder.append(c);
                } else if (Character.isLetter(c)) {
                    hasLetter = true;
                }
                if (i <= person.length() - 2 && person.substring(i, i + 2).equals("UP")) {
                    isUp = true;
                }
            }

            if (hasDigit &&!hasLetter) {
                stinginternalRequests.add(digitBuilder.toString());
            }
            if (hasLetter) {
                stringexternalRequests.add(digitBuilder.toString());
                direction.add(isUp);
            }
        }
        int q = 0;
        List<Integer> internalRequests = new LinkedList<>();
        List<Integer> externalRequests = new LinkedList<>();
        for (int i = 0; i < stinginternalRequests.size(); i++) {
            int addIn = Integer.parseInt(stinginternalRequests.get(i));
            if (!internalRequests.isEmpty()) {
                if(addIn==internalRequests.get(q-1)){
                    continue;
                }
            }
            if (addIn >= minfloor && addIn <= maxfloor) {
                internalRequests.add(addIn);
                q++;
            }
        }
        int w= 0;
        for (int i = 0; i < stringexternalRequests.size(); i++) {
            int addout = Integer.parseInt(stringexternalRequests.get(i));
            if (!externalRequests.isEmpty()) {
                if(addout==externalRequests.get(w-1)){
                    direction.remove(w-1);
                    continue;
                }
            }
            if(addout>=minfloor&&addout<=maxfloor){
                w++;
                externalRequests.add(addout);
            }
        }
        internalRequests.add(0);
        externalRequests.add(0);
        direction.add(false);
        internalRequests.add(0);
        externalRequests.add(0);
        direction.add(false);
        Elevator elevator = new Elevator(maxfloor, minfloor);
        System.out.printf("Current Floor: 1 Direction: UP\n");
        ExternalRequests externalRequest = new ExternalRequests(externalRequests, direction);
        RequestQueue requestQueue = new RequestQueue(internalRequests,externalRequest);
        Controller controller = new Controller(elevator, requestQueue);
    }
}
重构这东西足足用了我两天时间还只是大体的逻辑上一次的代码能对这次的不能对的那种,后续在调试过程中发现新代码的逻辑有问题于是在纸上重新写了一遍逻辑修改后测试点过了(但回寝室后室友拿我的代码看他的为啥过不了时意外发现我写的代码还是有bug,但有了一次经验的我马上就修改了这也就让我第三次实际上没怎么费力气就过了)简单拿纸详细介绍一下我电梯的运行逻辑。

就是按照纸上所写的
1.判断内外队列是否都为空了空了也就意味着程序该结束了
2.第一层不满足就该判断是否有一个是空的因为有一个是空的电梯就不必判断走哪个了直接走没空的那个就行了
3.若都不为空就开始判断电梯此时的方向与外部队列首个元素的方向的关系了同向的逻辑是一样的,反向的逻辑又是另一种,
(1)若同向内外假设当前电梯方向为上(若电梯方向为下时比较的方向相反)

<1>若外部请求与内部请求均大于当前楼层,比较哪个更小去哪个(总不能小的还没开门就过去吧)。

<2>若外部请求小于当前楼层内部请求大于当前楼层,去内部。(外部在下面电梯向上优先以电梯方向为主)

<3>若外部请求大于当前楼层内部请求小于当前楼层,去外部。(二者一上一下谁在上面去谁)

<4>若外部请求与内部请求均小于当前楼层,哪都不走,电梯转向。(因为没有删除队列的元素电梯转向后再次循环就进入到方向相反的逻辑中去的二没有死循环)

(2)若反向第一件事还是判断电梯方向(另一方向还是规律相反)

<1>若外部请求与内部请求均大于当前楼层或者若外部请求小于当前楼层内部请求大于当前楼层,都去内部(因为方向相反后如果走外部队列的话意味着电梯需要转向,而电梯上面还有内部队列可以走所以先走内部队列直到不满足条件)

<2>若外部请求大于当前楼层内部请求小于当前楼层,去外部并且电梯转向。(电梯上面已经没有内部队列了但有外部队列,所以走外部队列后)

<3>若外部请求与内部请求均小于当前楼层,哪都不走,电梯转向。(和上面的逻辑一样转向后就变成同向了走同向的逻辑)

上面的实际上就是判断内部请求和外部请求与电梯当前楼层的关系,然后按照要求的电梯逻辑走
简单来说就是我把所有电梯遇到的情况全部判断了一下所以一层if套一层if若仅用这一个方法写不进行拆分会显得代码量很大,但其可以将每一层if中的部分做成方法就可以拆分了,但我看着这张纸已经写的很全面了为啥我之前说我有Bug呢,因为方向相反的电梯运行逻辑是我后改的,第二次题目集中我仅仅判断当方向相反时直接走内部,但它还是过了(所以我就想问了不能多给几个测试点然后测试点上有信息么),因为第一次题目只有一个测试点,第二次题目只有两个测试点。

PTA第三次电梯

类图:
代码分析图:

看类图与上一次的对比就知道第三次我全套用了第二次的代码仅仅只是加了一个外部队列的目标请求队列并且外部队列的方向判定为外部队列与外部请求队列大小的比较
还是上代码:

点击查看代码
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

class Elevator {
    private int maxFloor;
    private int minFloor;
    private int nowFloor = 1;
    private boolean state = false;
    private boolean direction = true;
    public Elevator(int maxFloor, int minFloor) {
        setMaxFloor(maxFloor);
        setMinFloor(minFloor);
    }
    public void setMaxFloor(int maxFloor) {
        this.maxFloor = maxFloor;
    }
    public void setMinFloor(int minFloor) {
        this.minFloor = minFloor;
    }
    public int getNowFloor() {
        return nowFloor;
    }
    public boolean upOrDown() {
        return direction;
    }
    public void setDirection(boolean direction) {
        this.direction = direction;
    }
    public void setState(boolean state) {
        this.state = state;
    }
    public void setNowFloor(int nowFloor) {
        this.nowFloor = nowFloor;
    }
}

class RequestQueue {
    private List<Integer> internalRequests;
    private ExternalRequests externalRequests;
    public RequestQueue(List<Integer> internalRequests, ExternalRequests externalRequests) {
        setInternalRequests(internalRequests);
        setExternalRequests(externalRequests);
    }
    public List<Integer> getInternalRequests() {
        return internalRequests;
    }
    public ExternalRequests getExternalRequests() {
        return externalRequests;
    }
    public void setInternalRequests(List<Integer> internalRequests) {
        this.internalRequests = internalRequests;
    }
    public void setExternalRequests(ExternalRequests externalRequests) {
        this.externalRequests = externalRequests;
    }
}

class ExternalRequests {
    private List<Integer> externalRequests;
    private List<Boolean> direction;
    private List<Integer> needRequests;
    ExternalRequests(List<Integer> externalRequests, List<Integer> needRequests, List<Boolean> direction) {
        setExternalRequests(externalRequests);
        setDirection(direction);
        setNeedRequests(needRequests);
    }
    public List<Integer> getExternalRequests() {
        return externalRequests;
    }
    public List<Integer> getNeedRequests() {
        return needRequests;
    }
    public List<Boolean> getDirection() {
        return direction;
    }
    public void setExternalRequests(List<Integer> externalRequests) {
        this.externalRequests = externalRequests;
    }
    public void setNeedRequests(List<Integer> needRequests) {
        this.needRequests = needRequests;
    }
    public void setDirection(List<Boolean> direction) {
        this.direction = direction;
    }
}

class Controller {
    private Elevator elevator;
    private RequestQueue requestQueue;
    public Controller(Elevator elevator, RequestQueue requestQueue) {
        setElevator(elevator);
        setRequestQueue(requestQueue);
        while (true) {
            needFloor();
        }
    }
    public Elevator getElevator() {
        return elevator;
    }
    public RequestQueue getRequestQueue() {
        return requestQueue;
    }
    public void setElevator(Elevator elevator) {
        this.elevator = elevator;
    }
    public void setRequestQueue(RequestQueue requestQueue) {
        this.requestQueue = requestQueue;
    }
    public void needFloor() {
        int nowFloor = elevator.getNowFloor();
        int needFloor = 0;
        boolean direction = elevator.upOrDown();
        List<Integer> internalRequests = requestQueue.getInternalRequests();
        ExternalRequests external = requestQueue.getExternalRequests();
        List<Integer> externalRequests = external.getExternalRequests();
        List<Boolean> externalDirections = external.getDirection();
        List<Integer> needRequests = external.getNeedRequests();
        if (internalRequests.isEmpty() && externalRequests.isEmpty()) {
            System.exit(0);
        }
        int exNeedFloor = 0;
        boolean direction1 = false;
        int needAddFloor = 0;
        int inNeedFloor = 0;
        if (!externalRequests.isEmpty()) {
            exNeedFloor = externalRequests.get(0);
            direction1 = externalDirections.get(0);
            needAddFloor = needRequests.get(0);
        }
        if (!internalRequests.isEmpty()) {
            inNeedFloor = internalRequests.get(0);
        }
        if (!internalRequests.isEmpty() && !externalRequests.isEmpty()) {
            if (direction && direction1) {;
                                          
                if (nowFloor <= inNeedFloor && nowFloor <= exNeedFloor) {
                    needFloor = Math.min(exNeedFloor, inNeedFloor);
                    if (inNeedFloor > exNeedFloor) {
                        externalRequests.remove(0);
                        externalDirections.remove(0);
                        external.setDirection(externalDirections);
                        external.setExternalRequests(externalRequests);
                        internalRequests.add(needAddFloor);
                        requestQueue.setInternalRequests(internalRequests);
                        needRequests.remove(0);
                        external.setNeedRequests(needRequests);
                    } else {
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                    }
                    move(needFloor);
                } else if (nowFloor <= inNeedFloor && nowFloor >=exNeedFloor) {
                    needFloor = inNeedFloor;
                    internalRequests.remove(0);
                    requestQueue.setInternalRequests(internalRequests);
                    move(needFloor);
                } else if (nowFloor <= exNeedFloor && nowFloor >= inNeedFloor) {
                    needFloor = exNeedFloor;
                    externalRequests.remove(0);
                    externalDirections.remove(0);
                    external.setDirection(externalDirections);
                    external.setExternalRequests(externalRequests);
                    move(needFloor);
                    internalRequests.add(needAddFloor);
                    requestQueue.setInternalRequests(internalRequests);
                    needRequests.remove(0);
                    external.setNeedRequests(needRequests);
                } else if (nowFloor >= exNeedFloor && nowFloor >= inNeedFloor) {
                    direction = false;
                    elevator.setDirection(direction);
                }
            } else if (!(direction || direction1)) {
                if (nowFloor >= inNeedFloor && nowFloor >= exNeedFloor) {
                    needFloor = Math.max(exNeedFloor, inNeedFloor);
                    if (inNeedFloor < exNeedFloor) {
                        externalRequests.remove(0);
                        externalDirections.remove(0);
                        external.setDirection(externalDirections);
                        external.setExternalRequests(externalRequests);
                        internalRequests.add(needAddFloor);
                        requestQueue.setInternalRequests(internalRequests);
                        needRequests.remove(0);
                        external.setNeedRequests(needRequests);
                    } else {
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                    }
                    move(needFloor);
                } else if (nowFloor <= inNeedFloor && nowFloor >= exNeedFloor) {
                    needFloor = exNeedFloor;
                    externalRequests.remove(0);
                    externalDirections.remove(0);
                    external.setDirection(externalDirections);
                    external.setExternalRequests(externalRequests);
                    internalRequests.add(needAddFloor);
                    requestQueue.setInternalRequests(internalRequests);
                    needRequests.remove(0);
                    external.setNeedRequests(needRequests);
                    move(needFloor);
                } else if (nowFloor <= exNeedFloor && nowFloor >= inNeedFloor) {
                    needFloor = inNeedFloor;
                    internalRequests.remove(0);
                    requestQueue.setInternalRequests(internalRequests);
                    move(needFloor);
                } else if (nowFloor <= exNeedFloor && nowFloor <= inNeedFloor) {
                    direction = true;
                    elevator.setDirection(direction);
                }
            } else if (direction || direction1) {
                if (direction) {
                    if ((nowFloor <= inNeedFloor && nowFloor <= exNeedFloor) || (nowFloor <= inNeedFloor && nowFloor >= exNeedFloor)) {
                        needFloor = inNeedFloor;
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                        move(needFloor);
                    } else if (nowFloor >= inNeedFloor && nowFloor <= exNeedFloor) {
                        needFloor = exNeedFloor;
                        externalRequests.remove(0);
                        externalDirections.remove(0);
                        external.setDirection(externalDirections);
                        external.setExternalRequests(externalRequests);
                        internalRequests.add(needAddFloor);
                        requestQueue.setInternalRequests(internalRequests);
                        needRequests.remove(0);
                        external.setNeedRequests(needRequests);
                        move(needFloor);
                        direction = false;
                        elevator.setDirection(direction);
                    } else if (nowFloor >= exNeedFloor && nowFloor >= inNeedFloor) {
                        direction = false;
                        elevator.setDirection(direction);
                    }
                } else {
                    if ((nowFloor >= inNeedFloor && nowFloor >= exNeedFloor) || (nowFloor >= inNeedFloor && nowFloor <= exNeedFloor)) {
                        needFloor = inNeedFloor;
                        internalRequests.remove(0);
                        requestQueue.setInternalRequests(internalRequests);
                        move(needFloor);
                    } else if (nowFloor <= inNeedFloor && nowFloor >= exNeedFloor) {
                        needFloor = exNeedFloor;
                        externalRequests.remove(0);
                        externalDirections.remove(0);
                        external.setDirection(externalDirections);
                        external.setExternalRequests(externalRequests);
                        internalRequests.add(needAddFloor);
                        requestQueue.setInternalRequests(internalRequests);
                        needRequests.remove(0);
                        external.setNeedRequests(needRequests);
                        move(needFloor);
                        direction = true;
                        elevator.setDirection(direction);
                    } else if (nowFloor <= exNeedFloor && nowFloor <= inNeedFloor) {
                        direction = true;
                        elevator.setDirection(direction);
                    }
                }
            }
        } else if (internalRequests.isEmpty()) {
            if (!externalRequests.isEmpty()) {
                needFloor = externalRequests.get(0);
                externalRequests.remove(0);
                externalDirections.remove(0);
                external.setDirection(externalDirections);
                external.setExternalRequests(externalRequests);
                internalRequests.add(needAddFloor);
                requestQueue.setInternalRequests(internalRequests);
                needRequests.remove(0);
                external.setNeedRequests(needRequests);
                if (nowFloor < needFloor) {
                    direction = true;
                    elevator.setDirection(direction);
                } else {
                    direction = false;
                    elevator.setDirection(direction);
                }
                move(needFloor);
            }
        } else if (externalRequests.isEmpty()) {
            if (!internalRequests.isEmpty()) {
                needFloor = internalRequests.get(0);
                internalRequests.remove(0);
                requestQueue.setInternalRequests(internalRequests);
                if (nowFloor < needFloor) {
                    direction = true;
                    elevator.setDirection(direction);
                } else {
                    direction = false;
                    elevator.setDirection(direction);
                }
                move(needFloor);
            }
        }
    }
    public void move(int needFloor) {
        boolean direction = elevator.upOrDown();
        while (elevator.getNowFloor() != needFloor) {
            if (direction) {
                elevator.setNowFloor(elevator.getNowFloor() + 1);
                System.out.printf("Current Floor: %d Direction: UP\n", elevator.getNowFloor());
            } else {
                elevator.setNowFloor(elevator.getNowFloor() - 1);
                System.out.printf("Current Floor: %d Direction: DOWN\n", elevator.getNowFloor());
            }
        }
        System.out.printf("Open Door # Floor %d\nClose Door\n", needFloor);
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int minfloor = scan.nextInt();
        int maxfloor = scan.nextInt();
        scan.nextLine();
        List<Boolean> direction = new LinkedList<>();
        String regex1 = "<(\\d+),(\\d+)>";
        String regex2 = "<(\\d+)>";
        Pattern pattern1 = Pattern.compile(regex1);
        Pattern pattern2 = Pattern.compile(regex2);
        List<Integer> internalRequests = new LinkedList<>();
        List<Integer> externalRequests = new LinkedList<>();
        List<Integer> needRequests = new LinkedList<>();
        while (true) {
            String person = scan.nextLine();
            if (person.equalsIgnoreCase("END")) {
                break;
            }
            Matcher matcher1 = pattern1.matcher(person);
            Matcher matcher2 = pattern2.matcher(person);
            if (matcher2.find()) {
                if(Integer.parseInt(matcher2.group(1))>=minfloor&&Integer.parseInt(matcher2.group(1))<=maxfloor)
                    internalRequests.add(Integer.parseInt(matcher2.group(1)));
            }
            if (matcher1.find()) {
                externalRequests.add(Integer.parseInt(matcher1.group(1)));
                needRequests.add(Integer.parseInt(matcher1.group(2)));
            }
        }
        for (int i = 0; i < externalRequests.size(); i++) {
            if (externalRequests.get(i) < needRequests.get(i)) {
                direction.add(true);
            } else {
                direction.add(false);
            }
        }
        Elevator elevator = new Elevator(maxfloor, minfloor);
        System.out.printf("Current Floor: 1 Direction: UP\n");
        ExternalRequests externalRequest = new ExternalRequests(externalRequests, needRequests, direction);
        RequestQueue requestQueue = new RequestQueue(internalRequests, externalRequest);
        Controller controller = new Controller(elevator, requestQueue);
    }
}
这代码我改的也就是数据的读取部分,以及按照题目给提示当电梯去外部时将电梯外部请求队列添加到内部但说着简单但实际我却改了好久因为总会出现各种问题(因为第三次测试点有4个),把我第二次的代码的问题基本上全测出来了。 那么接下来我就分享一下我的踩坑心得吧。

三、踩坑心得

(1)不要仅有一点思路就开始写代码导致代码不可迭代:首先就是第一次这个没有踩什么坑(因为这个一一点点调试出来的),但这一却恰恰是最大的坑(无法进行迭代)对我第二题目的效率产生了极大的影响,所以写代码一定不要写那种史山(就是测试哪里错了就在哪里添加代码让它对),会导致代码逻辑及其混乱,不光别人看不懂我自己都看不懂。
实际上还有一个坑是因为第一次的题目集,因为第二次的代码实际上是按照第一次的想法逻辑写的但第一次用的是数组第二次用的是队列,数组是按照下表去进行移动的所以第一次的代码中有判断是否移动的部分,但第二次题目用的队列逻辑是走完就删,这可没办法回溯,于是又重新想了一遍回溯的原因是什么然后修改,还是第一次的代码与第二次的差别太大了,即使是用相同的逻辑也很难编写。
(2)不要过度相信自己的代码:其次就是第二次,首先就是第一个坑,即使测试用例过了也不要以为你的代码就对了,刚重构完时题目的测试用例和群里老师发的测试用例都能过,于是信心满满的就提交了,结果。。。

当时一点都没怀疑自己代码逻辑有问题陷入死循环了还以为是正则表达式时间复杂度超了,于是就有了上面那一串的运行超时后面在一张纸上重新写了一遍电梯的运行逻辑,所以说不行就动笔吧。
第二次修改完上面纸上的逻辑就过了,可能也是测试点少。
(3)但是第三次第二次的代码测试点没测出来的问题就出现了(但还好都在IDEA上测出来了)
<1>列表为空时提取了第一个元素导致非零返回

<2>正则表达式严格按照格式读取(但它可比我想象中的有用多了直接提取了<5,4>这种数据中的两个数字还能存在不同的列表里)

<3>能把代码拆分就尽量拆分,在将外部请求队列添加到内部时因为我全写在一个方法里导致有一个部分添加错了添加到外部去了导致部分正确

四、改进建议

1.目前的代码虽然实现了电梯调度功能,但是代码部分方法基本没有用到而部分方法中部分逻辑有过于重复且繁琐,可将其拆分为多个方法,这样不仅能提高代码的可读性,也便于进行后续的维护。

2.在一些可能越界的地方加入判断更好的检测到问题出现在哪,可以使用 try - catch 语句捕获可能出现的异常,便于快速定位和解决问题。

3.写一些优质代码也就是可复用的代码,避免重复计算,从而提高程序的运行效率。

4.写代码一定要写注释,要不然自己一段时间后自己都忘了还要重新看,降低效率,目前代码中的注释相对较少,尤其是在复杂的逻辑部分。应在关键代码段、方法定义、变量声明处添加详细的注释。对于每个方法,不仅要注释其功能,还要说明参数的含义。

五、总结

本次电梯题目并不算太难,唯一的难度就是电梯运行逻辑(刚开始一个人都做不出来可能就是只有一个测试用例分析不明白电梯的运行规则),这一次题目除了第一次剩下的两次都是第一次的迭代(前提是不要像我一样第一次写的代码几乎不可以迭代),要求只是保证单一职权原则,本次PTA作业深刻的让我了解到Java语言编码与C语言的编码差异,在编写代码前一定要先将结构确定好,本次题目中我就没有使用老师给的参考类图而是按照我的想法重新构造了一个框架(其实是为了避免查重)然后按照框架编写就好写很多了,并对类的概念,类与类之间的关系有了更深刻的了解,并且了解了列表以及正则表达式的如何使用,但对于正则表达式的学习还是不够到位,后续可以跟进学习,本次也对调试有了不一样的体会(这调试可太好用了!!!)。
对下一次题目唯一的建议就是多给几个测试用例和测试点(最好像本次的第三次题目一样)让我们一次就把所有的问题找出来不至于后续还要改Bug。

posted @ 2025-04-20 11:15  24201110-韩元昊  阅读(67)  评论(0)    收藏  举报