电梯模拟器的任务,任务解决了,一切正常,但被我需要收紧算法的话拒绝了。这是什么意思,还有什么办法可以解决这个问题?
/**
* Написать программу «симулятор лифта».
* Программа запускается из коммандной строки, в качестве параметров задается:
* кол-во этажей в подъезде - N (от 5 до 20);
* высота одного этажа;
* скорость лифта при движении в метрах в секунду (ускорением пренебрегаем, считаем, что когда лифт едет - он сразу едет с определенной скоростью);
* время между открытием и закрытием дверей.
*
* После запуска программа должна постоянно ожидать ввода от пользователя и выводить действия лифта в реальном времени.
* События, которые нужно выводить:
* лифт проезжает некоторый этаж;
* лифт открыл двери;
* лифт закрыл двери.
*
* Возможный ввод пользователя:
* вызов лифта на этаж из подъезда;
* нажать на кнопку этажа внутри лифта.
*
* Считаем, что пользователь не может помешать лифту закрыть двери.
* Все данные, которых не хватает в задаче можно выбрать на свое усмотрение.
* В результате должен получиться компилируемый код (в случае с java предлагается писать код в одном файле).
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
Elevator elevator = new Elevator(20, 3, 2, 2);
elevator.init();
}
private static class Elevator {
private static final long MILLISECONDS = 100; //1000
private final int doorTime;
private final int floors;
private final long floorSpeedSeconds;
private int currentFloor = 1;
private Elevator(int floors, int height, int speed, int doorTime) {
this.doorTime = doorTime;
this.floors = floors;
floorSpeedSeconds = height / speed * MILLISECONDS;
}
private void init() throws InterruptedException {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
Command command = new Command(scanner.nextLine());
if (command.targetFloor > floors) {
System.out.println("Target floor should be less than " + floors);
continue;
}
if (command.targetFloor > currentFloor) {
moveUp(command);
} else if (command.targetFloor < currentFloor) {
moveDown(command);
}
currentFloor = command.targetFloor;
openAndCloseDoor(doorTime);
}
}
private void printCurrentFloor(int i) {
System.out.println("Current floor is " + i);
}
private void openAndCloseDoor(int doorTime) throws InterruptedException {
System.out.println("Open door");
Thread.sleep(doorTime * MILLISECONDS);
System.out.println("Close door");
}
private void moveDown(Command command) throws InterruptedException {
for (int i = currentFloor; i >= command.targetFloor; i--) {
Thread.sleep(floorSpeedSeconds);
printCurrentFloor(i);
}
}
private void moveUp(Command command) throws InterruptedException {
for (int i = currentFloor; i <= command.targetFloor; i++) {
Thread.sleep(floorSpeedSeconds);
printCurrentFloor(i);
}
}
}
private static class Command {
private final PressType type;
private final int targetFloor;
private Command(String type) {
String[] commands = type.split(" ");
this.type = PressType.type(commands[0]);
this.targetFloor = parseInt(commands[1]);
}
}
private enum PressType {
IN("in"),
OUT("out");
private final String type;
PressType(String type) {
this.type = type;
}
private static PressType type(String s) {
return valueOf(s);
}
}
}
我会做一些不同的事情。
对于初学者来说,有一个关于实时的说法,即理论上电梯应该按自己的流程运行。
如果电梯在自己的流程中并且仍然接受命令,那么同步问题就出现了。如果命令在命令链中排列,这很容易解决。怎么做?利用
Executors.newSingleThreadExecutor()
此外,按下按钮并不意味着电梯会突然冲到那个楼层。按下按钮时电梯可能已经在移动,并且可能正在向相反方向移动。也就是说,理论上,按下按钮只是让电梯知道它,但是当电梯运行时,会有一个单独的问题。
当然,理想情况下,还必须考虑到一个人想去哪里(上或下)——这可能是从入口/电梯按下的意思。这很容易做到,但我不想让这个例子复杂化。
事实上,最简单的选择是这样的:当你点击按钮时,只需标记楼层并添加电梯的任务来驱动所有标记的楼层。如果电梯已经在移动并到达标记的楼层,它将停止并打开门。
代码看起来像这样(我不太擅长java,如果有问题,请见谅)
我们的 ExecutorService
按钮
检查是否需要向上移动
检查是否需要向下移动
运动本身
辅助代码
你可以这样开始这种快乐
原来是这样的
我认为,关于条件下实时的短语表明您需要能够在当前命令已经被执行时接受新命令。那些。“读取命令 - 执行”的方法并不好。考虑到新的传入命令,有必要优化电梯的运行。从这个意义上的算法的角度来看,这个问题更有趣也更困难。
我个人认为应该阅读 SOLID 和模式。并按照单一职责的第一原则去做。并查看命令方向和其他行为方向的模式。出于某种原因,您本身就有一部电梯,它正在等待命令并移动。使程序可以通过最小的更改从空间中的控制台接收来自文件的命令。关于算法,我不认为它们是从这项任务开始的。
我会以不同的方式完成这项工作。我会创建一个电梯类,从该类继承到楼层的呼叫按钮的 2 个类,以及机舱本身的按钮。电梯只有一种方法——移动(向上或向下)。所有从按钮接收到的命令,驱动到某个堆栈并依次执行。如果移动方向与调用重合,则在该楼层停止并从堆栈中移除。