BLOG-1

前言: 总结三次题目集的知识点、题量、难度等情况

题目集一:

单步电梯调度问题

一.设计与分析:

源代码设计:

电梯类:

 1 private int Max_Floor;        // 最大楼层
 2 private int Min_Floor;        // 最小楼层
 3 private static int Current_Floor = 0;     // 当前楼层
 4 private static String Direction = "UP";   // 运行方向(UP/DOWN)
 5 private static String Status = "STOP";    // 运行状态(STOP/RUN)
 6 private static Queue<String> InnerRequestQue = new LinkedList<>();  // 内部请求队列
 7 private static Queue<String> OutRequestQue = new LinkedList<>();    // 外部请求队列
 8 // 构造方法
 9 public Elevator(int Max_Floor, int Min_Floor, Queue<String> InnerRequest, Queue<String> OutRequest)
10 
11 // 获取内部请求的楼层和方向
12 public static int[] GetInFD()
13 
14 // 获取外部请求的楼层和方向  
15 public static int[] GetOutFD()
16 
17 // 判断下一次要去的楼层和方向
18 public static int[] GetNextFD(int in_f_d[], int out_f_d[])
19 
20 // 运行电梯到目标楼层
21 public static void RunElevator(int[] next_f_d)
22 
23 // 格式化输出电梯状态
24 public static void GetPrintf(int Current_Floor, String Direction, String Status)
25 
26 // 运行整部电梯
27 public static void Opreation()

主类:

1 static Scanner scanner = new Scanner(System.in);                           // 输入扫描器
2 static Queue<String> InnerRequestQue = new LinkedList<>();                // 内部请求队列
3 static Queue<String> OutRequestQue = new LinkedList<>();                  // 外部请求队列
4 
5 // 主方法
6 public static void main(String[] args)
7 
8 // 循环读取请求
9 public static void GetRequestScanf()

源代码分析:

1.圈复杂度分析:

image

 可以看到为改进的第一次电梯代码因为只设计了一个电梯类,一些方法的圈复杂度很高。

2.类图:

image

二.采坑心得:

本题目的重点在于如何设计正确的优先级,来选择出下一个要去的楼层。根据输入输出样例和题意很容易得出方向优先考虑,距离其次考虑的基本理念。但外部请求有一个乘客请求方向会让题目变得复杂。当请求方向与电梯前往目标运行方向不相同时需要特别考虑,这是我认为容易踩坑的地方,也是本题目的核心设计。

三.改进建议:

1.本次设计因为没有深入理解static变量,使用了太多static变量,实际应用中可能会出现很多问题,需要更改逻辑来消除静态变量。2.如“设计与分析”所示,本次设计圈复杂度过高,电梯类的设计也不符合单一功能原则,最需要改进的就是类设计的优化

题目集二:

单部电梯调度程序(类设计)

一.设计与分析:

源代码设计:

Direction枚举:

UP, DOWN, STOP

State枚举:

MOVING, STOPPED

电梯类:

1 private int currentFloor;      // 当前楼层
2 private Direction direction;   // 运行方向
3 private State state;          // 运行状态
4 private int minFloor;         // 最小楼层
5 private int maxFloor;         // 最大楼层

// 构造方法
public Elevator(int minFloor, int maxFloor)


// Getter和Setter方法
public int getCurrentFloor()
public void setCurrentFloor(int currentFloor)
public Direction getDirection()
public void setDirection(Direction direction)
public State getState()
public void setState(State state)
public int getMinFloor()
public int getMaxFloor()


// 业务方法
public boolean isValidFloor(int floor) // 验证楼层是否有效
public void moveUp() // 向上移动一层
public void moveDown() // 向下移动一层
public void openDoor() // 开门操作

 

控制器类:

 1 private Elevator elevator;    // 电梯对象
 2 private RequestQueue queue;   // 请求队列
 3 // 构造方法
 4 public Controller()
 5 public Controller(Elevator elevator, RequestQueue queue)
 6 
 7 // Getter和Setter方法
 8 public Elevator getElevator()
 9 public void setElevator(Elevator elevator)
10 public RequestQueue getQueue()
11 public void setQueue(RequestQueue queue)
12 
13 // 核心业务方法
14 public void processRequests()             // 处理所有请求
15 private void handleExternalRequest()      // 处理外部请求
16 private void handleInternalRequest()      // 处理内部请求
17 private void removeRequests(int currentFloor) // 移除已处理的请求
18 
19 // 辅助方法
20 private Direction internalRequestDirect()     // 获取内部请求方向
21 private Direction externalRequestDirect()     // 获取外部请求方向
22 private int externalRequestDistance()         // 计算外部请求距离
23 private int internalRequestDistance()         // 计算内部请求距离

请求队列类:

 1 private LinkedList<Integer> internalRequests = new LinkedList<>();      // 内部请求队列
 2 private LinkedList<ExternalRequest> externalRequests = new LinkedList<>(); // 外部请求队列
 3 // 添加请求方法
 4 public void addInternalRequest(int floor)             // 添加内部请求
 5 public void addExternalRequest(int floor, Direction direction) // 添加外部请求
 6 
 7 // 查询方法
 8 public boolean isEmpty()                              // 判断队列是否为空
 9 public boolean hasInternalRequests()                  // 是否有内部请求
10 public boolean hasExternalRequests()                  // 是否有外部请求
11 
12 // Getter方法
13 public LinkedList<Integer> getInternalRequests()      // 获取内部请求队列
14 public LinkedList<ExternalRequest> getExternalRequests() // 获取外部请求队列

外部请求类

1 private int floor;        // 请求楼层
2 private Direction direction; // 请求方向
3 // 构造方法
4 public ExternalRequest(int floor, Direction direction)
5 
6 // Getter方法
7 public int getFloor()
8 public Direction getDirection()

圈复杂度分析:

image

 类图:

image

 

二.采坑心得:

本次题目其实将第一次题目拆分成了多个类,重难点和第一次作业一样,Controler类中处理请求方法圈复杂度太高的原因是虽然分成了多个类,但代码核心集中在了一个方法中,所以设计代码要尽量多分几个方法。

三.改进建议:

本次迭代要求忽略重复请求,我是在输入中处理的,使得主类中代码较为冗杂,建议单独列出一个方法将重复请求在队列中处理掉。

题目集三:

单部电梯调度程序(类设计-迭代)

一.设计与分析:

源代码设计:

Direction枚举:

UP, DOWN, IDLE

State枚举:

MOVING, STOPPED

乘客类:

 1 private Integer sourceFloor = null;       // 源楼层(外部请求)
 2 private Integer destinationFloor = null;  // 目标楼层
 3 // 构造方法
 4 public Passenger()                                 // 无参构造
 5 public Passenger(Integer sourceFloor, Integer destinationFloor) // 外部请求初始化
 6 public Passenger(Integer destinationFloor)         // 内部请求初始化
 7 
 8 // Getter和Setter
 9 public Integer getSourceFloor()
10 public void setSourceFloor(Integer sourceFloor)
11 public Integer getDestinationFloor()
12 public void setDestinationFloor(Integer destinationFloor)
13 
14 // 业务方法
15 public Direction getDirection()                    // 获取外部请求目标方向

队列请求类:

private static RequestQueue instance;              // 单例实例
private LinkedList<Passenger> internalRequests = new LinkedList<>();  // 内部请求队列
private LinkedList<Passenger> externalRequests = new LinkedList<>();  // 外部请求队列
// 构造方法
private RequestQueue()                            // 私有构造

// 单例方法
public static RequestQueue getQueueInstance()     // 获取单例实例

// Getter和Setter
public LinkedList<Passenger> getInternalRequests()
public void setInternalRequests(LinkedList<Passenger> internalRequests)
public LinkedList<Passenger> getExternalRequests()
public void setExternalRequests(LinkedList<Passenger> externalRequests)

// 业务方法
public void addInternalRequest(Passenger passenger)  // 添加内部请求
public void addExternalRequest(Passenger passenger)  // 添加外部请求

电梯类:

private static Elevator instance;                 // 单例实例
private int currentFloor;                         // 当前楼层
private Direction direction = Direction.UP;       // 运行方向
private State state = State.STOPPED;              // 运行状态
private int maxFloor;                             // 最大楼层
private int minFloor;                             // 最小楼层
// 构造方法
private Elevator(int minFloor, int maxFloor)      // 私有构造

// 单例方法
public static Elevator getElevatorInstance(int minFloor, int maxFloor) // 获取单例实例

// Getter和Setter
public int getCurrentFloor()
public void setCurrentFloor(int currentFloor)
public Direction getDirection()
public void setDirection(Direction direction)
public State getState()
public void setState(State state)
public int getMaxFloor()
public int getMinFloor()

// 业务方法
public boolean isValidFloor(int floor)            // 验证楼层是否有效

控制类:

private Elevator elevator;                        // 电梯实例
private RequestQueue queue;                       // 请求队列实例
// 构造方法
public Controller(Elevator elevator, RequestQueue queue)

// Getter和Setter
public Elevator getElevator()
public void setElevator(Elevator elevator)
public RequestQueue getQueue()
public void setQueue(RequestQueue queue)

// 核心业务方法
public int getNextFloor()                         // 获取下一目标楼层
public Direction getDirection(int floor)          // 获取前往某请求方向
public boolean shouldStop(int floor)              // 检查当前楼层是否需要停留
public void removeRequestsAtCurrentFloor()        // 移除当前楼层的请求
public void moveOneFloor()                        // 移动到下一层
public void moveToFloor(int targetFloor)          // 运行到目标楼层
public void printFloorInfo(int currentFloor, Direction direction, boolean shouldStop) // 格式化输出
public void GO()                                  // 运行电梯

主类:

static Scanner scanner = new Scanner(System.in);  // 输入扫描器
static int Max_Floor, Min_Floor;                  // 楼层范围
// 主方法
public static void main(String[] args)

// 辅助方法
public static void readRequestScanf(RequestQueue queue) // 读取请求输入
public static boolean isValidScanf(int floor)           // 验证输入楼层有效性

圈复杂度分析:

image

类图:

image

二.采坑心得:

本此迭代用passsenger类代替了两种队列,同时外部请求出现了请求源楼层和请求目标楼层,而我又在输入时处理重复请求就导致读取输入时圈复杂度过高。但核心代码的圈复杂度得到了优化。此外,pta中我有一个得分点一直是运行超时,推测是处理队列请求的逻辑以及出队的时机有问题,导致某个情况下代码陷入了死循环。

三.改进建议:

根据踩坑心得,建议单独写一个处理输入的方法把数据全部读取到队列后再处理;另外,建议出队的时机放到电梯运行过程中,而不是获取到下一目标楼层后直接出队。

 总结:

  第一次作业思维还停留在面向过程。代码的核心是一个庞大的控制流程,用大量的if-else和状态变量来描述电梯“下一步该怎么做”。这导致主运行方法异常庞大,圈复杂度极高。二、三次作业逐渐学会了面向对象的“职责分配”。我意识到,系统应该由多个各司其职的对象协作完成,另外,让我感悟更深的是,类功能的分配更大程度上是让代码封装性更好,可读性更高,而设计出好的方法才更能降低代码的圈复杂度。除了知识上的收获,我还意识到,自己动手做一个较为复杂的项目,能大大提高自己思考,创作,解决问题的能力。

  意见:通过本次大作业,我觉得完成困难的原因是一些联系实际的的情况没有考虑到,建议可以用(注意)为同学们标注出一些特殊情况。另外,二三次作业都给出了类图,我觉得有些限制了我的思维,我的大部分代码都是完全按照给出的类图设计的,建议只给出基本要求,各个类的方法可以让同学自己先思考,后期再给出更好的类设计。

posted @ 2025-11-20 22:41  日式鱼  阅读(0)  评论(0)    收藏  举报