题目地址:
https://www.lintcode.com/problem/elevator-system-oo-design/description
设计一个大楼电梯系统。提供以下假设:
1、整个系统里只有
1
1
1个电梯,一共
n
n
n层;
2、每个电梯有三个状态,上升、下降、空闲;
3、当电梯往一个方向移动时,在电梯内无法按反向楼层。
具体看注释,代码如下:
import java.util.ArrayList;
import java.util.List;
enum Direction {
UP, DOWN
}
enum Status {
UP, DOWN, IDLE
}
class Request {
private int level;
public Request(int l) {
level = l;
}
public int getLevel() {
return level;
}
}
class ElevatorButton {
private int level;
private Elevator elevator;
public ElevatorButton(int level, Elevator e) {
this.level = level;
this.elevator = e;
}
public void pressButton() {
InternalRequest request = new InternalRequest(level);
elevator.handleInternalRequest(request);
}
}
class ExternalRequest extends Request {
private Direction direction;
public ExternalRequest(int l, Direction d) {
super(l);
// TODO Auto-generated constructor stub
this.direction = d;
}
public Direction getDirection() {
return direction;
}
}
class InternalRequest extends Request {
public InternalRequest(int l) {
super(l);
// TODO Auto-generated constructor stub
}
}
public class Elevator {
private List<ElevatorButton> buttons;
private List<Boolean> upStops;
private List<Boolean> downStops;
private int currLevel;
private Status status;
public Elevator(int n) {
buttons = new ArrayList<>();
// upStops存的是向上要停留的楼层的请求,downStops同理
upStops = new ArrayList<>();
downStops = new ArrayList<>();
currLevel = 0;
status = Status.IDLE;
// 一开始没有请求
for (int i = 0; i < n; i++) {
upStops.add(false);
downStops.add(false);
}
}
public void insertButton(ElevatorButton eb) {
buttons.add(eb);
}
// 接受外部请求
public void handleExternalRequest(ExternalRequest r) {
// Write your code here
// 如果外部请求是向上的,那么在upStops列表里记录之,
// 并且在没有向下请求的情况下,将状态改为向上(如果有向下的请求,则会先满足向下请求)
if (r.getDirection() == Direction.UP) {
upStops.set(r.getLevel() - 1, true);
if (noRequests(downStops)) {
status = Status.UP;
}
} else {
downStops.set(r.getLevel() - 1, true);
if (noRequests(upStops)) {
status = Status.DOWN;
}
}
}
// 接受内部请求,只接受同方向的请求,反方向的请求直接忽略
public void handleInternalRequest(InternalRequest r) {
// Write your code here
if (status == Status.UP) {
if (r.getLevel() >= currLevel + 1) {
upStops.set(r.getLevel() - 1, true);
}
} else if (status == Status.DOWN) {
if (r.getLevel() <= currLevel - 1) {
downStops.set(r.getLevel() - 1, true);
}
}
}
public void openGate() throws Exception {
// Write your code here
if (status == Status.UP) {
// 这里是在check下一次开门的位置。如果当前层向上没有要开门的位置,则从0开始继续找
for (int i = 0; i < upStops.size(); i++) {
int nextLevel = (currLevel + i) % upStops.size();
if (upStops.get(nextLevel)) {
currLevel = nextLevel;
upStops.set(nextLevel, false);
break;
}
}
} else if (status == Status.DOWN) {
for (int i = 0; i < downStops.size(); i++) {
int nextLevel = (currLevel + downStops.size() - i) % downStops.size();
if (downStops.get(nextLevel)) {
currLevel = nextLevel;
downStops.set(nextLevel, false);
break;
}
}
}
}
public void closeGate() {
// Write your code here
if (status == Status.IDLE) {
if (noRequests(downStops)) {
status = Status.UP;
return;
}
if (noRequests(upStops)) {
status = Status.DOWN;
}
} else if (status == Status.UP) {
if (noRequests(upStops)) {
if (noRequests(downStops)) {
status = Status.IDLE;
} else {
status = Status.DOWN;
}
}
} else {
if (noRequests(downStops)) {
if (noRequests(upStops)) {
status = Status.IDLE;
} else {
status = Status.UP;
}
}
}
}
private boolean noRequests(List<Boolean> stops) {
for (int i = 0; i < stops.size(); i++) {
if (stops.get(i)) {
return false;
}
}
return true;
}
public String elevatorStatusDescription() {
String description = "Currently elevator status is : " + status
+ ".\nCurrent level is at: " + (currLevel + 1)
+ ".\nup stop list looks like: " + upStops
+ ".\ndown stop list looks like: " + downStops
+ ".\n*****************************************\n";
return description;
}
}