Minecraft风格博客加载动画
MINEBLOG
0%
正在加载资源...

欢迎来到 content 2024 博客

你好(*´▽`)ノノ

pta题目集5~7《单部电梯调度》总结报告

pta题目集5~7《单部电梯调度》总结报告

目录

  • 前言
  • 设计与分析
  • 采坑心得
  • 自身改进
  • 总结

前言

在本次java课程的题目集5~7中,我们深入研究了单部电梯调度(即LOOK算法)问题。通过这一系列的练习,对LOOK算法JAVA中的不断学习,以及不断增加新的功能,我学到了很多:

  1. 熟悉了Java基本语法;
  2. 初步建立起了面向对象的设计思路;
  3. 正则表达式的认识及其进一步的了解;
  4. SourceMonitor代码分析软件的使用学习及其应用;
  5. 认识到了代码可拓展性的重要;

Complexity Metrics(复杂度分析)

因为下面要用到复杂度分析,所以先在此给出一些相关概念。
我们需要使用的主要是方法和类的复杂度分析。
方法的复杂度分析主要基于循环复杂度的计算。循环复杂度是一种表示程序复杂度的软件度量,由程序流程图中的“基础路径”数量得来。

  1. ev(G):即Essentail Complexity,用来表示一个方法的结构化程度,范围在[1,v(G)]​之间,值越大则程序的结构越“病态”,其计算过程和图的“缩点”有关。
  2. iv(G):即Design Complexity,用来表示一个方法和他所调用的其他方法的紧密程度,范围也在[1,v(G)]​之间,值越大联系越紧密
  3. v(G):即循环复杂度,可以理解为穷尽程序流程每一条路径所需要的试验次数。
    时间复杂度(Time Complexity)
  • 描述算法执行所需时间的增长率。通常以大O符号表示,反映算法在最坏情况下的效率。常见的时间复杂度包括:
    O(1):常数时间
    O(log n):对数时间(例如,二分查找)
    O(n):线性时间(例如,遍历一个数组)
    O(n log n):线性对数时间(例如,归并排序)
    O(n²):平方时间(例如,冒泡排序)
    空间复杂度(Space Complexity)

  • 衡量算法执行时所需内存的增长率。也使用大O符号表示。它包括:
    固定空间:算法运行时固定占用的空间
    可变空间:依赖于问题规模的输入而变化的空间

(只是一个初步的了解和借鉴,希望有大佬补充和修正(`・ω・´))

设计与分析

第一题题目描述

设计一个电梯类,包含电梯的最大楼层数、最小楼层数(默认为1层)、当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中电梯外部请求队列需区分上行和下行。电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客发起请求时(电梯外部乘客按下上行或下行按钮,或电梯内部乘客按下楼层数字按钮),电梯开始移动。电梯向某个方向移动时,优先处理同方向的请求,同方向请求处理完毕后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等。当电梯停止时,若有新请求,则根据请求方向或位置决定移动方向。电梯运行到某一楼层时,检查当前是否有请求(访问电梯内外请求队列),并据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,若有,则开门处理该楼层请求,然后关门继续移动。使用键盘模拟输入乘客请求,需处理无效请求(如超过最高或最低楼层的请求),并考虑电梯空闲状态,无请求时电梯停留在当前楼层。

题目分析

通过创建一个Room类(实际充当电梯系统的核心逻辑类)来处理电梯的运行逻辑。代码首先定义了电梯运行的基本参数,如最小楼层、最大楼层、当前楼层等,然后通过嵌套类In_Room和Out_Room分别表示电梯内部和外部的乘客请求。内部请求主要关注乘客在电梯内部选择的目标楼层,而外部请求则涉及乘客在楼层等待电梯时的方向选择(上行或下行)。代码利用一系列方法(如UP()、DOWN()和now())来处理和存储这些请求,并通过GO()方法实现电梯的实际运行逻辑。在运行过程中,代码通过循环和条件判断来模拟电梯的移动、开门、关门等动作,并根据请求队列的状态来决定电梯的运行方向和停止条件。
设计与实现

类设计

定义了一个Room类,该类通过嵌套的In_Room和Out_Room类来分别管理电梯内部和外部的乘客请求。In_Room类包含目标楼层和方向属性,用于表示乘客在电梯内部的请求;Out_Room类则包含所在楼层和方向属性,用于表示乘客在楼层等待电梯时的外部请求。Room类本身包含了一系列方法,如UP()用于处理上行内部请求,DOWN()用于处理下行内部请求,now()用于处理外部请求,以及GO()方法用于启动电梯并根据请求队列执行相应的动作。GO()方法是核心,它通过循环和条件判断来模拟电梯的运行,包括移动、开门、关门等操作,并在请求队列为空时停止电梯。

核心逻辑

其实在一开始时,笔者想,既然是判断单个电梯问题,那么我们可以用数字和数组来记录这部电梯要到达哪一个楼层以及该楼层所对应的时段方向,所以,我便在这里用sum来计入该对应楼层在用户请求中出现了几次,以及对其上一次操作进行判断来确定其运行方向(其实这一步就有很大问题,与题目的双队列已经相差十万八千里了),以这个思路,写下代码:

点击查看代码
import java.util.Scanner;
import java.lang.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.applet.*;
public class Main {
    static int sum=0;
    static int sum1=0;
    public static void main(String[] args){
        class Room{
            int MinRoom,MaxRoom;
            int NowRoom=1;
            int firstRoom;
            class RChange{
                int ChangeNumber=0;
                int changeUP=0;
                int changeDown=0;
                int changeNow=0;
            }
            RChange[] RoomChange;
            public void setRoomChange(int MinRoom,int MaxRoom) {
                RoomChange=new RChange[MaxRoom+1];
                for(int i=MinRoom;i<=MaxRoom;i++){
                    this.RoomChange[i]=new RChange();
                }
            }
            public void UP(int r){
                RoomChange[r].changeUP++;
                RoomChange[r].ChangeNumber++;
                sum++;
            }
            public void DOWN(int r){
                RoomChange[r].changeDown++;
                RoomChange[r].ChangeNumber++;
                sum++;
            }
            public void now(int r){
                RoomChange[r].changeNow++;
                RoomChange[r].ChangeNumber++;
                sum++;
            }
            public void FirstUPgo(){
                while(sum>0){
                    int tq=NowRoom;
                    for(int i=MaxRoom;i>=NowRoom;i--){
                        if(RoomChange[i].ChangeNumber > 0){
                            tq=i;
                            break;
                        }
                    }
                    if(tq>=NowRoom){
                        do{
                            System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                            if(NowRoom<tq&&RoomChange[NowRoom].ChangeNumber>0&& (RoomChange[NowRoom].changeNow != 0 && sum1 != 0|| RoomChange[NowRoom].changeUP != 0)){
                                System.out.println("Open Door # Floor "+NowRoom);
                                System.out.println("Close Door");
                                RoomChange[NowRoom].ChangeNumber--;
                                if(RoomChange[NowRoom].changeUP!=0){
                                    RoomChange[NowRoom].changeUP--;
                                    sum1++;
                                }
                                else{
                                    RoomChange[NowRoom].changeNow--;
                                }
                                sum--;
                            }
                            NowRoom++;
                        }while(NowRoom<tq);
                        System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                        System.out.println("Open Door # Floor "+NowRoom);
                        System.out.printf("Close Door");
                        RoomChange[NowRoom].ChangeNumber--;
                        if(RoomChange[NowRoom].changeDown!=0){
                            RoomChange[NowRoom].changeDown--;
                            sum1++;
                        }
                        else {
                            RoomChange[NowRoom].changeNow--;
                        }
                        sum--;
                    }
                    if(sum==0){
                        return;
                    }
                    for(int i=MinRoom;i<=NowRoom;i++) {
                        if (RoomChange[i].ChangeNumber > 0) {
                            tq = i;
                            break;
                        }
                    }
                    if(tq<=NowRoom){
                        System.out.println();
                        NowRoom--;
                        do{
                            System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                            if(NowRoom>tq&&RoomChange[NowRoom].ChangeNumber>0&&(RoomChange[NowRoom].changeNow!=0 && sum1 != 0||RoomChange[NowRoom].changeDown!=0)){
                                System.out.println("Open Door # Floor "+NowRoom);
                                System.out.println("Close Door");
                                RoomChange[NowRoom].ChangeNumber--;
                                if(RoomChange[NowRoom].changeDown!=0){
                                    RoomChange[NowRoom].changeDown--;
                                    sum1++;
                                }
                                else {
                                    RoomChange[NowRoom].changeNow--;
                                }
                                sum--;
                            }
                            NowRoom--;
                        }while(NowRoom>tq);
                        System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                        System.out.println("Open Door # Floor "+NowRoom);
                        System.out.print("Close Door");
                        RoomChange[NowRoom].ChangeNumber--;
                        if(RoomChange[NowRoom].changeUP!=0){
                            RoomChange[NowRoom].changeUP--;
                            sum1++;
                        }
                        else{
                            RoomChange[NowRoom].changeNow--;
                        }
                        sum--;
                    }
                    if(sum!=0){
                        System.out.println();
                    }
                }
            }
        }
        Room room = new Room();
        Scanner input = new Scanner(System.in);
        room.MinRoom = input.nextInt();
        room.MaxRoom = input.nextInt();
        room.setRoomChange(room.MinRoom, room.MaxRoom);
        input.nextLine();
        while(true){
            String ch;
            ch = input.nextLine();
            String pattern=ch;
            String FoundUp = "UP";
            String FoundDown = "DOWN";
            Pattern p=Pattern.compile(FoundUp);
            Matcher S=p.matcher(pattern);
            if (ch.equalsIgnoreCase("end")) {
                break;
            }
            if (S.find()) {
                Pattern numberPattern = Pattern.compile("\\d+");
                Matcher numberMatcher = numberPattern.matcher(pattern);
                if (numberMatcher.find()) {
                    int TRoom = Integer.parseInt(numberMatcher.group());
                    if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom) {
                        if(sum==0){
                            room.firstRoom=1;
                        }
                        room.UP(TRoom);
                    }
                }
            }
            else{
                p=Pattern.compile(FoundDown);
                S=p.matcher(pattern);
                if(S.find()) {
                    Pattern numberPattern = Pattern.compile("\\d+");
                    Matcher numberMatcher = numberPattern.matcher(pattern);
                    if (numberMatcher.find()) {
                        int TRoom = Integer.parseInt(numberMatcher.group());
                        if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom) {
                            if(sum==0){
                                room.firstRoom=-1;
                            }
                            room.DOWN(TRoom);
                        }
                    }
                }
                else{
                    Pattern numberPattern = Pattern.compile("\\d+");
                    Matcher numberMatcher = numberPattern.matcher(pattern);
                    if (numberMatcher.find()) {
                        int TRoom = Integer.parseInt(numberMatcher.group());
                        if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom) {
                            room.now(TRoom);
                        }
                    }
                }
            }
        }
        room.FirstUPgo();
    }
}

但是问题也很明显,没有遵循LOOK算法的核心:先判断是否同向,再判断距离大小!,笔者只考虑了如何将这一些请求移入至数据中,随之就导致了只有单队列的运行方式,在一些情况无法满足LOOK算法和题目的双队列请求操作。
EG:

1
10
<3,UP>
<2>
END

错误输出:

Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
Current Floor: 2 Direction: DOWN
Current Floor: 1 Direction: DOWN
Open Door # Floor 1
Close Door

正确输出:

Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Open Door # Floor 2
Close Door
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
  • 可以明显的看到错误的代码不仅方向出错了,它的电梯甚至还到达了一楼!

正确代码中在GO()方法中,代码首先检查内部和外部请求队列是否为空。如果队列不为空,电梯开始运行。运行时,代码以电梯的当前运行方向为主导,结合当前楼层、外部请求队列的队头和内部请求队列的队头,通过一系列复杂的条件判断来决定电梯的移动方向。电梯每次移动一个楼层后,都会检查是否需要停靠以处理请求,如果是,则执行开门和关门动作。代码中使用了多个循环和条件分支来处理不同情况下的电梯行为,确保电梯能够按照方向优先的原则处理请求,直至所有请求都被处理完毕,队列为空时电梯停止运行。在整个过程中,代码通过打印输出来模拟电梯的运行状态,如当前楼层、运行方向、开门和关门动作等,从而实现了对电梯运行过程的详细模拟。

  • floor1.java的SourceMonitor分析
  • 类图分析

    从图数据来看,平均复杂度,最大复杂度,方法平均语句都很高,说明代码的深度较大,复杂度高,不够清晰,运行效率很低。这可能是运行条件的判断较多,后续可以考虑优化,降低复杂度,提高代码运行效率。

问题分析

笔者在写的时候发现了自己诸多问题:

  • 代码结构问题
    嵌套类的过度使用 :Room 类中嵌套了 In_Room 和 Out_Room 类,这种设计使得类之间的关系较为紧密,增加了代码的复杂度。在 Java 中,过度使用嵌套类会导致代码的可读性和可维护性降低,因为嵌套类的生命周期与外部类相关联,外部类的实例必须存在才能创建嵌套类的实例,这在一定程度上限制了代码的灵活性和复用性。(再也不用数组死磕了┭┮﹏┭┮)
  • 类的职责不清晰 :Room 类不仅负责处理电梯的运行逻辑,还包含了请求队列的存储和管理等功能,导致类的职责过于繁杂,违背了单一职责原则(SRP)。这使得代码难以理解和维护,因为一个类承担了过多的不同职责,当其中某一部分功能需要修改时,可能会影响到其他部分的功能。
  • 代码可读性问题
    变量命名不规范 :代码中的变量命名较为随意,例如 temp、Max、Min、target、target1、turn 等,这些变量的命名未能清晰地表达其含义和用途。对于阅读代码的人来说,难以通过变量名快速理解其在代码中的作用,增加了理解代码的难度,降低了代码的可读性。
    /*(这个问题笔者认为是相对而言及其重要的,笔者会在日后对书写规范学习)//
  • 缺乏注释 :整个代码中几乎没有注释,对于复杂的逻辑和算法部分,没有进行任何解释和说明。这使得其他开发者在阅读和理解代码时,需要花费大量时间去分析代码的意图和实现细节,不利于团队协作和后续的代码维护。
  • 请求处理问题
    请求队列管理混乱 :in_room 和 out_room 数组用于存储内部和外部请求,但是通过数组索引来管理请求队列的方式较为原始,并且在代码中对这些数组的处理不够严谨。例如,在添加新请求时,没有对数组越界情况进行处理,可能导致数组越界异常;在移除已处理的请求时,没有及时清理数组中的无效数据,可能会影响电梯的运行逻辑。
  • 无法处理重复请求 :代码没有对重复的乘客请求进行处理,如果乘客连续多次输入相同的请求,代码会将其视为多个独立的请求进行处理,这可能导致电梯不必要的停靠和动作,影响电梯的运行效率。
  • 电梯运行逻辑问题
    运行方向判断复杂 :在 GO() 方法中,电梯运行方向的判断逻辑较为复杂,涉及到多个条件判断和循环嵌套。这种复杂的逻辑结构容易导致代码的可读性和可维护性降低,并且在某些情况下可能出现逻辑错误,影响电梯的正常运行,例如电梯可能无法正确地按照方向优先原则处理请求。
  • 缺乏对电梯空闲状态的优化 :当电梯没有请求时,虽然代码中提到了电梯停留在当前楼层,但没有进一步的优化逻辑来处理电梯的空闲状态。例如,在空闲状态下,电梯可以返回到某个指定的楼层(如 1 层)等待下一个请求,以提高电梯的响应速度和服务效率。
  • 输入验证问题
    输入格式敏感 :代码对输入格式的要求较为严格,例如电梯外部请求的格式必须为 “<乘客所在楼层数 , 乘梯方向>”,且乘梯方向必须大写(UP、DOWN)。如果输入格式不符合要求,代码可能无法正确解析请求,甚至会抛出异常,导致程序运行出错。
  • 缺乏对输入错误的处理 :对于无效的输入,如非数字字符、无效的楼层号等,代码没有进行充分的验证和处理。虽然在添加请求时对楼层是否在有效范围内进行了一些判断,但对于其他类型的输入错误没有进行处理,可能导致程序出现异常或运行结果不符合预期。
  • 性能问题
    循环和条件判断过多 :在 GO() 方法中,存在大量的循环和条件判断语句,这可能导致代码的运行效率较低。特别是在请求队列较长或楼层较多的情况下,多次循环和复杂的条件判断会增加程序的执行时间,影响电梯模拟的实时性和流畅性。
  • 资源浪费 :由于代码的结构和逻辑不够优化,可能会导致一些不必要的资源浪费。例如,数组的频繁分配和扩展、不必要的对象创建等,都可能增加程序的内存占用和运行时间。

题目一代码附录

点击查看代码
import java.util.*;
import java.util.regex.*;

 class Room {
    int temp = 0;
    int Max = Integer.MIN_VALUE;
    int Min = Integer.MAX_VALUE;
    int target = 0;
    int target1 = 0;
    int turn = 1;
    int MinRoom, MaxRoom;
    int NowRoom = 1;
    In_Room[] in_room;
    Out_Room[] out_room;
    int[] TEMP;
    int INRoomnum = 0;
    int OUTRoomnum = 0;

    class In_Room {
        int in_room_turn;
        int in_room_num;
    }

    public void STOP() {
        in_room = new In_Room[MaxRoom + 1];
        out_room = new Out_Room[MaxRoom + 1];
        TEMP = new int[MaxRoom + 1];
        for (int i = 0; i <= MaxRoom; i++) {
            this.in_room[i] = new In_Room();
            this.out_room[i] = new Out_Room();
        }
    }

    class Out_Room {
        int out_room_turn;
        int out_room_num;
    }

    public void UP(int TRoom) {
        temp = TRoom;
        in_room[INRoomnum] = new In_Room();
        in_room[INRoomnum].in_room_num = TRoom;
        in_room[INRoomnum].in_room_turn = 1;
        INRoomnum++;
        if (TRoom < Min) {
            Min = TRoom;
        } else {
            Max = TRoom;
        }
    }

    public void DOWN(int TRoom) {
        temp = TRoom;
        in_room[INRoomnum] = new In_Room();
        in_room[INRoomnum].in_room_num = TRoom;
        in_room[INRoomnum].in_room_turn = -1;
        INRoomnum++;
        if (TRoom < Min) {
            Min = TRoom;
        } else {
            Max = TRoom;
        }
    }

    public void now(int TRoom) {
        temp = TRoom;
        if (OUTRoomnum == 0) {
            out_room[OUTRoomnum] = new Out_Room();
            out_room[OUTRoomnum].out_room_turn = 1;
            out_room[OUTRoomnum].out_room_num = TRoom;
            OUTRoomnum++;
            if (TRoom < Min) {
                Min = TRoom;
            } else {
                Max = TRoom;
            }
        } else {
            if (out_room[OUTRoomnum - 1].out_room_num < TRoom) {
                out_room[OUTRoomnum] = new Out_Room();
                out_room[OUTRoomnum].out_room_turn = 1;
                out_room[OUTRoomnum].out_room_num = TRoom;
                OUTRoomnum++;
                if (TRoom < Min) {
                    Min = TRoom;
                } else {
                    Max = TRoom;
                }
            } else {
                out_room[OUTRoomnum] = new Out_Room();
                out_room[OUTRoomnum].out_room_turn = -1;
                out_room[OUTRoomnum].out_room_num = TRoom;
                OUTRoomnum++;
                if (TRoom < Min) {
                    Min = TRoom;
                } else {
                    Max = TRoom;
                }
            }
        }
    }

    public void GO() {
        int temp1 = 0, temp2 = 0;
        if (target == 0) {
            target = Math.min(out_room[temp1].out_room_num, in_room[temp2].in_room_num);
            if (in_room[temp2].in_room_num == Math.min(out_room[temp1].out_room_num, in_room[temp2].in_room_num) && in_room[temp2].in_room_turn == -1) {
                target = out_room[temp1].out_room_num;
            }
            if (out_room[temp1].out_room_num == 0) {
                target = in_room[temp2].in_room_num;
            }
            if (in_room[temp2].in_room_num == 0) {
                target = out_room[temp1].out_room_num;
            }
            if (target == out_room[temp1].out_room_num) {
                if (in_room[temp2].in_room_num == out_room[temp1].out_room_num)
                    temp2++;
                temp1++;
            } else {
                if (in_room[temp2].in_room_num == out_room[temp1].out_room_num)
                    temp1++;
                temp2++;
            }
        }
        while (temp1 + temp2 <= OUTRoomnum + INRoomnum) {
            while (NowRoom != target) {
                if (target > NowRoom) {
                    if (target1 == NowRoom) {
                        if (turn == 1)
                            System.out.println("Current Floor: " + NowRoom + " Direction: UP");
                        else
                            System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
                        System.out.println("Open Door # Floor " + NowRoom);
                        System.out.println("Close Door");
                        NowRoom++;
                        target1 = -1;
                        turn = 1;
                        continue;
                    }
                    turn = 1;
                    System.out.println("Current Floor: " + NowRoom + " Direction: UP");
                    NowRoom++;
                } else {
                    if (target1 == NowRoom) {
                        if (turn == 1)
                            System.out.println("Current Floor: " + NowRoom + " Direction: UP");
                        else
                            System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
                        System.out.println("Open Door # Floor " + NowRoom);
                        System.out.println("Close Door");
                        NowRoom--;
                        target1 = -1;
                        turn = -1;
                        continue;
                    }
                    turn = -1;
                    System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
                    NowRoom--;
                }
            }
            if (temp1 + temp2 == OUTRoomnum + INRoomnum - 1) {
                int l = 1;
                if (turn == 1) {
                    System.out.println("Current Floor: " + NowRoom + " Direction: UP");
                    System.out.println("Open Door # Floor " + NowRoom);
                    System.out.println("Close Door");
                } else {
                    System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
                    System.out.println("Open Door # Floor " + NowRoom);
                    System.out.println("Close Door");
                }
                if (out_room[temp1].out_room_num == NowRoom || in_room[temp2].in_room_num == NowRoom) {
                    System.out.println("Open Door # Floor " + NowRoom);
                    System.out.println("Close Door");
                    return;
                }
                if (temp1 == OUTRoomnum - 1) {
                    target = out_room[temp1].out_room_num;
                    if (out_room[temp1].out_room_num == 0)
                        return;
                } else {
                    target = in_room[temp2].in_room_num;
                    if (in_room[temp2].in_room_num == 0)
                        return;
                }
                while (NowRoom != target) {
                    if (target > NowRoom) {
                        if (l > 0) {
                            NowRoom++;
                            turn = 1;
                            l--;
                            continue;
                        }
                        turn = 1;
                        System.out.println("Current Floor: " + NowRoom + " Direction: UP");
                        NowRoom++;
                    } else {
                        if (l > 0) {
                            NowRoom--;
                            turn = -1;
                            l--;
                            continue;
                        }
                        turn = -1;
                        System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
                        NowRoom--;
                    }
                }
                if (turn == 1)
                    System.out.println("Current Floor: " + NowRoom + " Direction: UP");
                else
                    System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
                System.out.println("Open Door # Floor " + NowRoom);
                System.out.println("Close Door");
                return;
            }
            if (NowRoom != target) {
                if (target > NowRoom) {
                    if (target1 == NowRoom) {
                        turn = 1;
                        NowRoom++;
                        continue;
                    }
                    turn = 1;
                    System.out.println("Current Floor: " + NowRoom + " Direction: UP");
                    NowRoom++;
                } else {
                    if (target1 == NowRoom) {
                        turn = -1;
                        NowRoom--;
                        continue;
                    }
                    turn = -1;
                    System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
                    NowRoom--;
                }
            }
            if (target == NowRoom) {
                int i;
                int turn1 = turn;
                do {
                    i = 0;
                    int t1 = 0;
                    int t2 = 0;
                    if (turn == 1) {
                        if (in_room[temp2].in_room_num > NowRoom) {
                            t2 = turn;
                        } else
                            t2 = -turn;
                        if (out_room[temp1].out_room_num > NowRoom) {
                            t1 = turn;
                        } else {
                            t1 = -turn;
                        }
                        if (in_room[temp2].in_room_turn == -1 && in_room[temp2].in_room_num < out_room[temp1].out_room_num)
                            t2 = -turn;
                    } else {
                        if (in_room[temp2].in_room_num < NowRoom) {
                            t2 = turn;
                        } else
                            t2 = -turn;
                        if (out_room[temp1].out_room_num < NowRoom) {
                            t1 = turn;
                        } else {
                            t1 = -turn;
                        }
                        if (in_room[temp2].in_room_turn == 1 && in_room[temp2].in_room_num > out_room[temp1].out_room_num)
                            t2 = -turn;
                    }
                    if (in_room[temp2].in_room_num == 0) {
                        target = out_room[temp1].out_room_num;
                        temp1++;
                        target1 = NowRoom;
                        continue;
                    }
                    if (out_room[temp1].out_room_num == 0) {
                        target = in_room[temp2].in_room_num;
                        temp2++;
                        target1 = NowRoom;
                        continue;
                    }
                    if (t1 == t2 && turn == t1) {
                        if (Math.min(Math.abs(in_room[temp2].in_room_num - NowRoom), Math.abs(out_room[temp1].out_room_num - NowRoom)) == Math.abs(in_room[temp2].in_room_num - NowRoom)) {
                            target = in_room[temp2].in_room_num;
                            if (in_room[temp2].in_room_num == out_room[temp1].out_room_num)
                                temp1++;
                            temp2++;
                            target1 = NowRoom;
                        } else {
                            target = out_room[temp1].out_room_num;
                            if (in_room[temp2].in_room_num == out_room[temp1].out_room_num)
                                temp2++;
                            temp1++;
                            target1 = NowRoom;
                        }
                    } else {
                        if (t1 == turn) {
                            target = out_room[temp1].out_room_num;
                            if (in_room[temp2].in_room_num == out_room[temp1].out_room_num)
                                temp2++;
                            temp1++;
                            target1 = NowRoom;
                        } else if (t2 == turn) {
                            target = in_room[temp2].in_room_num;
                            if (in_room[temp2].in_room_num == out_room[temp1].out_room_num)
                                temp1++;
                            temp2++;
                            target1 = NowRoom;
                        } else if (t2 == t1) {
                            turn = t1;
                            i = 1;
                        }
                    }
                } while (i == 1);
                turn = turn1;
            }
        }
        if (NowRoom != target) {
            if (turn == 1)
                System.out.println("Current Floor: " + NowRoom + " Direction: UP");
            else
                System.out.println("Current Floor: " + NowRoom + " Direction: DOWN");
            System.out.println("Open Door # Floor " + NowRoom);
            System.out.println("Close Door");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Room room = new Room();
        Scanner input = new Scanner(System.in);
        room.MinRoom = input.nextInt();
        room.MaxRoom = input.nextInt();
        room.STOP();
        input.nextLine();
        while (true) {
            String ch;
            ch = input.nextLine();
            String pattern = ch;
            String FoundUp = "UP";
            String FoundDown = "DOWN";
            Pattern p = Pattern.compile(FoundUp);
            Matcher S = p.matcher(pattern);
            if (ch.equalsIgnoreCase("end")) {
                break;
            }
            if (S.find()) {
                Pattern numberPattern = Pattern.compile("\\d+");
                Matcher numberMatcher = numberPattern.matcher(pattern);
                if (numberMatcher.find()) {
                    int TRoom = Integer.parseInt(numberMatcher.group());
                    if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom && room.temp != TRoom) {
                        room.UP(TRoom);
                    }
                }
            } else {
                p = Pattern.compile(FoundDown);
                S = p.matcher(pattern);
                if (S.find()) {
                    Pattern numberPattern = Pattern.compile("\\d+");
                    Matcher numberMatcher = numberPattern.matcher(pattern);
                    if (numberMatcher.find()) {
                        int TRoom = Integer.parseInt(numberMatcher.group());
                        if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom && room.temp != TRoom) {
                            room.DOWN(TRoom);
                        }
                    }
                } else {
                    Pattern numberPattern = Pattern.compile("\\d+");
                    Matcher numberMatcher = numberPattern.matcher(pattern);
                    if (numberMatcher.find()) {
                        int TRoom = Integer.parseInt(numberMatcher.group());
                        if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom && room.temp != TRoom) {
                            room.now(TRoom);
                        }
                    }
                }
            }
        }
        room.GO();
    }
}

第二题题目描述

本题要求对电梯调度程序进行迭代优化,遵循单一职责原则(SRP),重新设计类结构。设计的类必须包括但不限于电梯类、乘客请求类、队列类以及控制类。电梯运行规则与之前设计相同,但需要处理以下两种新情况:

  • 乘客请求的楼层数超出电梯的最高或最低楼层数范围,程序应自动忽略此类无效请求。
  • 乘客请求存在连续重复的情况,例如“<3><3><3>”“<5,DOWN><5,DOWN>”,程序需自动过滤掉多余的相同请求,仅保留一个
  • 输入格式为:第一行输入最小电梯楼层数,第二行输入最大电梯楼层数,从第三行开始每行输入一个乘客请求。电梯内乘客请求格式为“<楼层数>”,电梯外乘客请求格式为“<乘客所在楼层数,乘梯方向>”,其中乘梯方向用“UP”表示上行,用“DOWN”表示下行(UP、DOWN必须大写)。当输入“end”时,表示输入结束(不区分大小写)。
  • 输出格式为:模拟电梯的运行过程。当电梯运行到某一楼层且不需要停留开门时,输出一行文本:“Current Floor: 楼层数 Direction: 方向”;当电梯运行到某一楼层且需要停留开门时,输出两行文本:“Open Door # Floor 楼层数”和“Close Door”。

题目分析

与之前的单类设计不同,本次设计严格遵循单一职责原则,将系统划分为多个独立的类,每个类负责特定的功能模块。以下是各个类的分析:

· 乘客请求类

用于封装乘客的请求信息,包括乘客所在楼层、目标楼层以及乘梯方向等。通过该类,可以方便地对乘客请求进行存储和管理,同时也便于后续对请求进行过滤和处理。

· 请求队列类

专门用于存储和管理乘客的请求队列,包括电梯内部乘客的请求队列和电梯外部乘客的请求队列。该类提供了添加请求、移除请求以及获取队列头部请求等功能,确保电梯能够按照正确的顺序处理乘客的请求。
电梯类
主要负责管理电梯的基本运行状态和行为,例如当前楼层、运行方向、运行状态等。电梯类通过与请求队列类的交互,获取乘客的请求,并根据电梯的运行规则执行相应的操作,如移动电梯、开门关门等。
控制类
作为电梯调度的核心协调者,控制类负责接收乘客的请求,对请求进行预处理(包括过滤无效请求和相同的多余请求),然后将有效的请求添加到请求队列中,并通知电梯类开始运行。在整个电梯调度过程中,控制类起到了指挥和协调的关键作用,确保电梯能够按照正确的逻辑运行。

类设计

  • 乘客请求类 :负责封装乘客的请求信息,如所在楼层、目标楼层和乘梯方向等。
  • 请求队列类 :用于存储和管理乘客的请求队列,支持添加、移除和获取队列头部请求等操作。
  • 电梯类 :管理电梯的基本运行状态和行为,例如当前楼层、运行方向和运行状态等,并根据请求队列执行相应的电梯操作。
  • 控制类 :作为核心调度类,负责接收乘客请求,对请求进行预处理,协调电梯类和请求队列类之间的交互,控制电梯的运行过程。

这种设计遵循单一职责原则,将不同的职责分配给不同的类,使得每个类的职责更加明确,代码结构更加清晰,便于后续的维护和扩展。

核心逻辑

吸取了上一次不认真审题的教训,笔者从最核心的GO()函数下手,由于这一道题要求了我们要把重复的情况进行一个判断,所以笔者是这么想的:

public void UP(int TRoom){
                //去重操作
                temp=TRoom;
                in_room[INRoomnum]=new In_Room();in_room[INRoomnum].in_room_num=TRoom;in_room[INRoomnum].in_room_turn=1;INRoomnum++;
                if(TRoom<Min){
                    Min=TRoom;
                }
                else
                    Max=TRoom;
            }
            public void DOWN(int TRoom){
                //去重操作
                temp=TRoom;
                in_room[INRoomnum]=new In_Room();in_room[INRoomnum].in_room_num=TRoom;in_room[INRoomnum].in_room_turn=-1;INRoomnum++;
                if(TRoom<Min){
                    Min=TRoom;
                }
                else
                    Max=TRoom;
            }
            public void now(int TRoom){
                //去重操作
                temp=TRoom;
                if(OUTRoomnum==0){
                    out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
                    if(TRoom<Min) {
                        Min = TRoom;
                    }
                    else
                        Max=TRoom;
                }
                else{
                    if(out_room[OUTRoomnum-1].out_room_num<TRoom){
                        out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
                        if(TRoom<Min){
                            Min=TRoom;
                        }else
                            Max=TRoom;
                    }
                    else{
                        out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=-1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
                        if(TRoom<Min){
                            Min=TRoom;
                        }else
                            Max=TRoom;
                    }
                }
            }
.......
//main函数内部
//取上升代码举例:
Pattern numberPattern = Pattern.compile("\\d+");
                Matcher numberMatcher = numberPattern.matcher(pattern);
                if (numberMatcher.find()) {
                    //记录这一次的楼层数
                    int TRoom = Integer.parseInt(numberMatcher.group());
                    //判断楼层数是否在限制范围内,并判断是否与上次引入楼层数相冲突
                    if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom&&room.temp!=TRoom) {
                        room.UP(TRoom);
                    }

既然要进行重复性判断,那么在初始引入楼层时,我利用了temp这个变量(有一个好心人在和笔者互测代码时告诉笔者这个是温度的意思,笔者是英语渣,别骂了),来记录上一个楼层是什么,从而实现去重效果。
控制类接收乘客请求后,首先对请求进行预处理,过滤掉无效的楼层数请求和连续重复的多余请求。然后,将有效的请求添加到相应的请求队列中,并通知电梯类开始运行。电梯类在运行时,根据请求队列中的请求,按照电梯的运行规则(如方向优先原则)决定电梯的移动方向和停靠楼层。每次电梯移动一个楼层后,都会检查是否需要停靠以处理请求,若需要,则执行开门和关门动作。整个运行过程中,电梯类不断与请求队列类交互,获取新的请求并更新电梯的状态,直至所有请求都被处理完毕,电梯回到空闲状态。

  • floor2.java
  • 类图分析

(其实可以看出,作者的史山代码无法使得代码的复杂程度下降,希望有哪位大佬来分享一下你的思路─=≡Σ(((つ•̀ω•́)つ)

题目二代码附录:

点击查看代码
import java.util.*;
import java.util.regex.*;
class Room{
    int temp=0;int Max=Integer.MIN_VALUE;
    int Min=Integer.MAX_VALUE;int target=0;int target1=0;int turn=1;int MinRoom,MaxRoom;int NowRoom=1;In_Room []in_room;Out_Room []out_room;int []TEMP;int INRoomnum=0;int OUTRoomnum=0;
    class In_Room{
        int in_room_turn;int in_room_num;
    }
    public void STOP(){
        in_room=new In_Room[MaxRoom+1];out_room=new Out_Room[MaxRoom+1];TEMP=new int[MaxRoom+1];
        for(int i=0;i<=MaxRoom;i++) {
            this.in_room[i]=new In_Room();this.out_room[i]=new Out_Room();
        }
    }
    class Out_Room{
        int out_room_turn;int out_room_num;
    }
    public void UP(int TRoom){
        temp=TRoom;
        in_room[INRoomnum]=new In_Room();in_room[INRoomnum].in_room_num=TRoom;in_room[INRoomnum].in_room_turn=1;INRoomnum++;
        if(TRoom<Min){
            Min=TRoom;
        }
        else
            Max=TRoom;
    }
    public void DOWN(int TRoom){
        temp=TRoom;
        in_room[INRoomnum]=new In_Room();in_room[INRoomnum].in_room_num=TRoom;in_room[INRoomnum].in_room_turn=-1;INRoomnum++;
        if(TRoom<Min){
            Min=TRoom;
        }
        else
            Max=TRoom;
    }
    public void now(int TRoom){
        temp=TRoom;
        if(OUTRoomnum==0){
            out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
            if(TRoom<Min) {
                Min = TRoom;
            }
            else
                Max=TRoom;
        }
        else{
            if(out_room[OUTRoomnum-1].out_room_num<TRoom){
                out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
                if(TRoom<Min){
                    Min=TRoom;
                }else
                    Max=TRoom;
            }
            else{
                out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=-1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
                if(TRoom<Min){
                    Min=TRoom;
                }else
                    Max=TRoom;
            }
        }
    }
    public void GO(){
        int temp1=0,temp2=0;
        if(target==0){
            target=Math.min(out_room[temp1].out_room_num,in_room[temp2].in_room_num);
            if(in_room[temp2].in_room_num==Math.min(out_room[temp1].out_room_num,in_room[temp2].in_room_num)&&in_room[temp2].in_room_turn==-1){
                target=out_room[temp1].out_room_num;
            }
            if(out_room[temp1].out_room_num==0){
                target=in_room[temp2].in_room_num;
            }
            if(in_room[temp2].in_room_num==0){
                target=out_room[temp1].out_room_num;
            }
            if(target==out_room[temp1].out_room_num){
                if(in_room[temp2].in_room_num==out_room[temp1].out_room_num)
                    temp2++;
                temp1++;
            }
            else{
                if(in_room[temp2].in_room_num==out_room[temp1].out_room_num)
                    temp1++;
                temp2++;
            }
        }
        while(temp1+temp2<=OUTRoomnum+INRoomnum){
            while(NowRoom!=target){
                if(target>NowRoom){
                    if(target1==NowRoom){
                        if(turn==1)
                            System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                        else
                            System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                        System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");NowRoom++;target1=-1;turn=1;
                        continue;
                    }
                    turn=1;System.out.println("Current Floor: "+NowRoom+" Direction: UP");NowRoom++;
                }
                else{
                    if(target1==NowRoom){
                        if(turn==1)
                            System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                        else
                            System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                        System.out.println("Open Door # Floor "+NowRoom);
                        System.out.println("Close Door");NowRoom--;target1=-1;turn=-1;
                        continue;
                    }
                    turn=-1;
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                    NowRoom--;
                }
            }
            if(temp1+temp2==OUTRoomnum+INRoomnum-1){
                int l=1;
                if(turn==1){
                    System.out.println("Current Floor: "+NowRoom+" Direction: UP");System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
                }
                else{
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
                }
                if(out_room[temp1].out_room_num==NowRoom||in_room[temp2].in_room_num==NowRoom){
                    System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");return;
                }
                if(temp1==OUTRoomnum-1){
                    target=out_room[temp1].out_room_num;
                    if(out_room[temp1].out_room_num==0)
                        return;
                }
                else{
                    target=in_room[temp2].in_room_num;
                    if(in_room[temp2].in_room_num==0)
                        return;
                }
                while(NowRoom!=target){
                    if(target>NowRoom){
                        if(l>0){
                            NowRoom++;
                            turn=1;
                            l--;
                            continue;
                        }
                        turn=1;
                        System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                        NowRoom++;
                    }
                    else{
                        if(l>0){
                            NowRoom--;
                            turn=-1;
                            l--;
                            continue;
                        }
                        turn=-1;
                        System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                        NowRoom--;
                    }
                }
                if(turn==1)
                    System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                else
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
                return;
            }
            if(NowRoom!=target){
                if(target>NowRoom){
                    if(target1==NowRoom){
                        turn=1;
                        NowRoom++;
                        continue;
                    }
                    turn=1;
                    System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                    NowRoom++;
                }
                else{
                    if(target1==NowRoom){
                        turn=-1;
                        NowRoom--;
                        continue;
                    }
                    turn=-1;
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                    NowRoom--;
                }
            }
            if(target==NowRoom){
                int i;
                int turn1=turn;
                do{
                    i=0;
                    int t1=0;
                    int t2=0;
                    if(turn==1){
                        if(in_room[temp2].in_room_num>NowRoom){
                            t2=turn;
                        }
                        else
                            t2=-turn;
                        if(out_room[temp1].out_room_num>NowRoom){
                            t1=turn;
                        }
                        else{
                            t1=-turn;
                        }
                        if(in_room[temp2].in_room_turn==-1&&in_room[temp2].in_room_num<out_room[temp1].out_room_num)
                            t2=-turn;
                    }
                    else{
                        if(in_room[temp2].in_room_num<NowRoom){
                            t2=turn;
                        }
                        else
                            t2=-turn;
                        if(out_room[temp1].out_room_num<NowRoom){
                            t1=turn;
                        }
                        else{
                            t1=-turn;
                        }
                        if(in_room[temp2].in_room_turn==1&&in_room[temp2].in_room_num>out_room[temp1].out_room_num)
                            t2=-turn;
                    }
                    if(in_room[temp2].in_room_num==0){
                        target=out_room[temp1].out_room_num;
                        temp1++;
                        target1=NowRoom;
                        continue;
                    }
                    if(out_room[temp1].out_room_num==0){
                        target=in_room[temp2].in_room_num;
                        temp2++;
                        target1=NowRoom;
                        continue;
                    }
                    if(t1==t2&&turn==t1){
                        if(Math.min(Math.abs(in_room[temp2].in_room_num-NowRoom),Math.abs(out_room[temp1].out_room_num-NowRoom))==Math.abs(in_room[temp2].in_room_num-NowRoom)){
                            target=in_room[temp2].in_room_num;
                            if(in_room[temp2].in_room_num==out_room[temp1].out_room_num)
                                temp1++;
                            temp2++;
                            target1=NowRoom;
                        }
                        else{
                            target=out_room[temp1].out_room_num;
                            if(in_room[temp2].in_room_num==out_room[temp1].out_room_num)
                                temp2++;
                            temp1++;
                            target1=NowRoom;
                        }
                    }
                    else{
                        if(t1==turn){
                            target=out_room[temp1].out_room_num;
                            if(in_room[temp2].in_room_num==out_room[temp1].out_room_num)
                                temp2++;
                            temp1++;
                            target1=NowRoom;
                        }
                        else if(t2==turn){
                            target=in_room[temp2].in_room_num;
                            if(in_room[temp2].in_room_num==out_room[temp1].out_room_num)
                                temp1++;
                            temp2++;
                            target1=NowRoom;
                        }
                        else if(t2==t1){
                            turn=t1;
                            i=1;
                        }
                    }
                }while(i==1);
                turn=turn1;
            }
        }
        if(NowRoom!=target){
            if(turn==1)
                System.out.println("Current Floor: "+NowRoom+" Direction: UP");
            else
                System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
            System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
        }
    }
}
public class Main {
    public static void main(String[] args){
        Room room = new Room();
        Scanner input = new Scanner(System.in);
        room.MinRoom = input.nextInt();
        room.MaxRoom = input.nextInt();
        room.STOP();
        input.nextLine();
        while(true){
            String ch;
            ch = input.nextLine();
            String pattern=ch;
            String FoundUp = "UP";
            String FoundDown = "DOWN";
            Pattern p=Pattern.compile(FoundUp);
            Matcher S=p.matcher(pattern);
            if (ch.equalsIgnoreCase("end")) {
                break;
            }
            if (S.find()) {
                Pattern numberPattern = Pattern.compile("\\d+");
                Matcher numberMatcher = numberPattern.matcher(pattern);
                if (numberMatcher.find()) {
                    int TRoom = Integer.parseInt(numberMatcher.group());
                    if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom&&room.temp!=TRoom) {
                        room.UP(TRoom);
                    }
                }
            }
            else{
                p=Pattern.compile(FoundDown);
                S=p.matcher(pattern);
                if(S.find()) {
                    Pattern numberPattern = Pattern.compile("\\d+");
                    Matcher numberMatcher = numberPattern.matcher(pattern);
                    if (numberMatcher.find()) {
                        int TRoom = Integer.parseInt(numberMatcher.group());
                        if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom&&room.temp!=TRoom) {
                            room.DOWN(TRoom);
                        }
                    }
                }
                else{
                    Pattern numberPattern = Pattern.compile("\\d+");Matcher numberMatcher = numberPattern.matcher(pattern);
                    if (numberMatcher.find()) {
                        int TRoom = Integer.parseInt(numberMatcher.group());
                        if (TRoom >= room.MinRoom && TRoom <= room.MaxRoom&&room.temp!=TRoom) {
                            room.now(TRoom);
                        }
                    }
                }
            }
        }
        room.GO();
    }
}

第三题题目描述

对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客类、队列类以及控制类。
电梯运行规则与前阶段相同,但有如下变动情况:

  • 乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
  • 对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)。

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

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

运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door

设计要求

类的设计:程序必须包含以下类,并遵循单一职责原则(SRP):

电梯类:管理电梯的状态和行为。
乘客类:表示乘客及其请求信息。
队列类:处理乘客请求的队列。
控制类:调度电梯和乘客请求。

请求格式的变化:

外部请求格式:<请求源楼层,请求目的楼层>,既包括乘客请求的来源楼层和目标楼层。
内部请求队列的更新:电梯处理完外部请求后,需将目的楼层加入内部队列。

逻辑分析:

其实这道题只是在输入格式上发生了一个改变,实质上还是同样的思路:
在我们引入判断时,若为内部队列,则同上处理;反之,若为外部队列,我们则用一个队列来单独储存后面我们所要添加的楼层,再按题目要求,在到达外部队列中的楼层时,将对应的楼层进行引入

// 用初始化楼层举例,temp3对应的是临时储存队列的头指针。
// 初始化目标楼层
        if (target == 0) {
            target = Math.min(out_room[temp1].out_room_num, in_room[temp2].in_room_num);

            // 根据请求的方向和目标楼层调整目标
            if (in_room[temp2].in_room_num == Math.min(out_room[temp1].out_room_num, in_room[temp2].in_room_num) && in_room[temp2].in_room_turn == -1) {
                target = out_room[temp1].out_room_num;
            }
            if (out_room[temp1].out_room_num == 0) {
                target = in_room[temp2].in_room_num;
            }
            if (in_room[temp2].in_room_num == 0) {
                target = out_room[temp1].out_room_num;
            }

            // 处理临时队列中的请求
            if (target == in_room[temp2].in_room_num) {
                now(temp_room[temp3].temp_room_num);
                TEMPRoomnum--;
                temp3++;
            }
            if (target == out_room[temp1].out_room_num) {
                temp1++;
            } else {
                temp2++;
            }
        }

  • floor3.java

  • 类图

(其实,在分析这个问题时还有一个更加简便的操作,在处理完内,外部队列的引入后,可以直接将临时队列的数据直接接在内部队列后,这是因为外部队列的出队列顺序固定的,那么临时队列的入队顺序也是固定的。)

题目三代码附录:

点击查看代码
import java.util.*;
import java.util.regex.*;
class Room{
    int target=0;int target1=0;int turn=1;int MinRoom,MaxRoom;int NowRoom=1;In_Room []in_room;Out_Room []out_room;int []TEMP;int INRoomnum=0;int OUTRoomnum=0;
    Temp_Room[] temp_room;int TEMPRoomnum=0;
    class In_Room{
        int in_room_turn;int in_room_num;
    }
    public void STOP(){
        in_room=new In_Room[MaxRoom+1];out_room=new Out_Room[MaxRoom+1];TEMP=new int[MaxRoom+1];temp_room=new Temp_Room[MaxRoom+1];
        for(int i=0;i<=MaxRoom;i++) {
            this.in_room[i]=new In_Room();this.out_room[i]=new Out_Room();this.temp_room[i]=new Temp_Room();
        }
    }
    class Out_Room{
        int out_room_turn;int out_room_num;
    }
    class Temp_Room{
        int temp_room_num;
    }
    public void UP(int TRoom){
        in_room[INRoomnum]=new In_Room();in_room[INRoomnum].in_room_num=TRoom;in_room[INRoomnum].in_room_turn=1;INRoomnum++;
    }
    public void TEMP(int TRoom){
        temp_room[TEMPRoomnum]= new Temp_Room();temp_room[TEMPRoomnum].temp_room_num=TRoom;
        TEMPRoomnum++;
    }
    public void DOWN(int TRoom){
        in_room[INRoomnum]=new In_Room();in_room[INRoomnum].in_room_num=TRoom;in_room[INRoomnum].in_room_turn=-1;INRoomnum++;
    }
    public void now(int TRoom){
        if(OUTRoomnum==0){
            out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
        }
        else{
            if(out_room[OUTRoomnum-1].out_room_num<TRoom){
                out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
            }
            else{
                out_room[OUTRoomnum]=new Out_Room();out_room[OUTRoomnum].out_room_turn=-1;out_room[OUTRoomnum].out_room_num=TRoom;OUTRoomnum++;
            }
        }
    }
    public void GO(){
        int temp1=0,temp2=0,temp3=0;
        if(target==0){
            target=Math.min(out_room[temp1].out_room_num,in_room[temp2].in_room_num);
            if(in_room[temp2].in_room_num==Math.min(out_room[temp1].out_room_num,in_room[temp2].in_room_num)&&in_room[temp2].in_room_turn==-1){
                target=out_room[temp1].out_room_num;
            }
            if(out_room[temp1].out_room_num==0){
                target=in_room[temp2].in_room_num;
            }
            if(in_room[temp2].in_room_num==0){
                target=out_room[temp1].out_room_num;
            }
            if(target==in_room[temp2].in_room_num){
                now(temp_room[temp3++].temp_room_num);TEMPRoomnum--;
            }
            if(target==out_room[temp1].out_room_num){
                temp1++;
            }
            else{
                temp2++;
            }
        }
        while(temp1+temp2<=OUTRoomnum+INRoomnum+TEMPRoomnum){
            while(NowRoom!=target){
                if(target>NowRoom){
                    if(target1==NowRoom){
                        if(turn==1)
                            System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                        else
                            System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                        System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");NowRoom++;target1=-1;turn=1;
                        continue;
                    }
                    turn=1;System.out.println("Current Floor: "+NowRoom+" Direction: UP");NowRoom++;
                }
                else{
                    if(target1==NowRoom){
                        if(turn==1)
                            System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                        else
                            System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                        System.out.println("Open Door # Floor "+NowRoom);
                        System.out.println("Close Door");NowRoom--;target1=-1;turn=-1;
                        continue;
                    }
                    turn=-1;
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                    NowRoom--;
                }
            }
            if(temp1+temp2==OUTRoomnum+INRoomnum-1+TEMPRoomnum){
                int l=1;
                if(turn==1){
                    System.out.println("Current Floor: "+NowRoom+" Direction: UP");System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
                }
                else{
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
                }
                if(out_room[temp1].out_room_num==NowRoom||in_room[temp2].in_room_num==NowRoom){
                    System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");return;
                }
                if(temp1==OUTRoomnum-1){
                    target=out_room[temp1].out_room_num;
                    if(out_room[temp1].out_room_num==0)
                        return;
                }
                else if(temp2==INRoomnum+TEMPRoomnum-1){
                    target=in_room[temp2].in_room_num;
                    if(in_room[temp2].in_room_num==0)
                        return;
                }
                while(NowRoom!=target){
                    if(target>NowRoom){
                        if(l>0){
                            NowRoom++;
                            turn=1;
                            l--;
                            continue;
                        }
                        turn=1;
                        System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                        NowRoom++;
                    }
                    else{
                        if(l>0){
                            NowRoom--;
                            turn=-1;
                            l--;
                            continue;
                        }
                        turn=-1;
                        System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                        NowRoom--;
                    }
                }
                if(turn==1)
                    System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                else
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
                return;
            }
            if(NowRoom!=target){
                if(target>NowRoom){
                    if(target1==NowRoom){
                        turn=1;
                        NowRoom++;
                        continue;
                    }
                    turn=1;
                    System.out.println("Current Floor: "+NowRoom+" Direction: UP");
                    NowRoom++;
                }
                else{
                    if(target1==NowRoom){
                        turn=-1;
                        NowRoom--;
                        continue;
                    }
                    turn=-1;
                    System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
                    NowRoom--;
                }
            }
            if(target==NowRoom){
                int i;
                int turn1=turn;
                do{
                    i=0;
                    int t1=0;
                    int t2=0;
                    if(turn==1){
                        if(in_room[temp2].in_room_num>NowRoom){
                            t2=turn;
                        }
                        else
                            t2=-turn;
                        if(out_room[temp1].out_room_num>NowRoom){
                            t1=turn;
                        }
                        else{
                            t1=-turn;
                        }
                        if(in_room[temp2].in_room_turn==-1&&in_room[temp2].in_room_num<out_room[temp1].out_room_num)
                            t2=-turn;
                    }
                    else{
                        if(in_room[temp2].in_room_num<NowRoom){
                            t2=turn;
                        }
                        else
                            t2=-turn;
                        if(out_room[temp1].out_room_num<NowRoom){
                            t1=turn;
                        }
                        else{
                            t1=-turn;
                        }
                        if(in_room[temp2].in_room_turn==1&&in_room[temp2].in_room_num>out_room[temp1].out_room_num)
                            t2=-turn;
                    }
                    if(in_room[temp2].in_room_num==0){
                        target=out_room[temp1].out_room_num;
                        temp1++;
                        target1=NowRoom;
                        continue;
                    }
                    if(out_room[temp1].out_room_num==0){
                        target=in_room[temp2].in_room_num;
                        temp2++;
                        if(temp_room[temp3].temp_room_num!=0){
                            now(temp_room[temp3++].temp_room_num);TEMPRoomnum--;
                        }
                        target1=NowRoom;
                        continue;
                    }
                    if(t1==t2&&turn==t1){
                        if(Math.min(Math.abs(in_room[temp2].in_room_num-NowRoom),Math.abs(out_room[temp1].out_room_num-NowRoom))==Math.abs(in_room[temp2].in_room_num-NowRoom)){
                            target=in_room[temp2].in_room_num;
                            temp2++;
                            if(temp_room[temp3].temp_room_num!=0){
                                now(temp_room[temp3++].temp_room_num);TEMPRoomnum--;
                            }
                            target1=NowRoom;
                        }
                        else{
                            target=out_room[temp1].out_room_num;
                            temp1++;
                            target1=NowRoom;
                        }
                    }
                    else{
                        if(t1==turn){
                            target=out_room[temp1].out_room_num;
                            temp1++;
                            target1=NowRoom;
                        }
                        else if(t2==turn){
                            target=in_room[temp2].in_room_num;
                            temp2++;
                            if(temp_room[temp3].temp_room_num!=0){
                                now(temp_room[temp3++].temp_room_num);TEMPRoomnum--;
                            }
                            target1=NowRoom;
                        }
                        else if(t2==t1){
                            turn=t1;
                            i=1;
                        }
                    }
                }while(i==1);
                turn=turn1;
            }
        }
        if(NowRoom!=target){
            if(turn==1)
                System.out.println("Current Floor: "+NowRoom+" Direction: UP");
            else
                System.out.println("Current Floor: "+NowRoom+" Direction: DOWN");
            System.out.println("Open Door # Floor "+NowRoom);System.out.println("Close Door");
        }
    }
}
public class Main {
    public static void main(String[] args){
        Room room = new Room();
        Scanner input = new Scanner(System.in);
        room.MinRoom = input.nextInt();
        room.MaxRoom = input.nextInt();
        room.STOP();
        input.nextLine();
        while (true) {
            String ch;
            ch = input.nextLine();
            if (ch.equalsIgnoreCase("end")) {
                break;
            }
            Pattern pattern = Pattern.compile("<(\\d+)>");
            Matcher matcher = pattern.matcher(ch);
            Pattern commandPattern = Pattern.compile("<(\\d+),(\\d+)>");
            Matcher commandMatcher = commandPattern.matcher(ch);
            if (commandMatcher.find()) {
                int firstNumber = Integer.parseInt(commandMatcher.group(1));
                int secondNumber = Integer.parseInt(commandMatcher.group(2));
                if (firstNumber < secondNumber) {
                    if (firstNumber >= room.MinRoom && firstNumber <= room.MaxRoom) {
                        room.UP(firstNumber);
                        room.TEMP(secondNumber);
                    }
                } else if (firstNumber > secondNumber) {
                    if (firstNumber >= room.MinRoom && firstNumber <= room.MaxRoom) {
                        room.DOWN(firstNumber);
                        room.TEMP(secondNumber);
                    }
                }else room.now(firstNumber);
            }
            else if(matcher.find()){
                int firstNumber = Integer.parseInt(matcher.group(1));
                if (firstNumber >= room.MinRoom && firstNumber <= room.MaxRoom){
                    room.now(firstNumber);
                }
            }
        }
        room.GO();
    }
}

采坑心得

在实现电梯调度的过程中,我遇到了许多挑战和问题。以下是一些关键的采坑心得:

  • 读题问题:了解题目的需求十分重要,第一个题目便是在读题时,没有抓住题目中LOOK算法的双队列要求,导致代码的底层逻辑出错

  • 在分析题目时,采用固有思维,自以为是,不知变通,在未理解题目规则时就上手写代码,最后还是与同学交流才理解这种独具创新的电梯运行规则;

  • 存储数据时,一昧的用C语言的思维用数组存储数据,不知道采用ArrayList<>高效存储并处理数据;

  • 在判断队列是否为空时,直接想当然的认为if(List!=null),这种表达是明显的逻辑错误,实则是通过if(List.size()!=0)或者if(!List.isEmpty()),建议使用后者,更不会报警告;

  • 注释问题:更好的注释能让他人更好的了解代码的用意及其逻辑,但在这三题目中,由于自身问题,未能将注释良好的进行写入;

  • 代码扩展性差 :由于代码的结构和逻辑较为紧密缺乏清晰的类设计模块划分,使得代码的扩展性较差。如果需要添加新的功能或对现有功能进行修改,可能会涉及到大量的代码改动,增加了开发和维护的难度。

  • 循环和条件判断过多 :在 GO() 方法中,存在大量的循环和条件判断语句,这可能导致代码的运行效率较低。特别是在请求队列较长或楼层较多的情况下,多次循环和复杂的条件判断会增加程序的执行时间,影响电梯模拟的实时性和流畅性。(史山代码现在还是不清楚如何处理,求大佬带飞( • ̀ω•́ )✧)

自身改进

基于以上对三个题目的分析和对问题的反思,我罗列以下几点改进:

  1. 降低代码复杂度:通过进一步的模块化和抽象,可以降低代码的复杂度,提高可读性和可维护性。
  2. 增强调度算法的智能性:可以考虑引入更多的调度策略,如基于机器学习的动态调度算法,以适应不同的场景。
  3. 提高代码的可测试性:通过设计更易测试的接口和类结构,可以更方便地进行单元测试和集成测试。
  4. 遵循单一职责原则:提高代码的可读性(注释过少,养成写注释的好习惯)和可维护性。

总结

通过这次对单部电梯调度问题的深入研究,不仅提升了面向对象设计的能力,还在代码优化和问题解决方面积累了宝贵的经验。在三次题目中,习得了正则表达式的灵活运用,主要是各个方法和类的实现的到了训练,当然,还有读题能力,也在这几道题的磨炼中得到了升华。同时,也将更加注重代码的质量和可维护性,努力写出更高效的代码,同时减少像if,while等史山代码的出现,优化自身的逻辑思路。

posted on 2025-04-20 11:09  content2024  阅读(73)  评论(0)    收藏  举报

导航