美文网首页
电梯运行程序模拟

电梯运行程序模拟

作者: hjx_zju | 来源:发表于2019-07-15 00:43 被阅读0次

​ 日常生活中,大家都坐过电梯,有时候会想想电梯在每个人按下键之后是怎么运行的呢?这是个看起来似乎简单但想清楚却也不容易的问题。

​ 给电梯的运行进行建模。电梯在运行过程中会载人同时接受外部的请求,这样我们可以用两个队列来表示载人信息和请求信息。对于乘客来说,其信息主要是当前楼层和目标楼层,为了方便打印,给每个乘客命名。电梯的运行有三种状态:WAIT(停),UP(上),DOWN(下)。电梯根据载人队列和请求队列来更新自己的状态,在每一层都判断是否可以进人(针对请求队列),出人(针对载人队列)。下面是运行算法图示。

image-20190714143300244

​ 当电梯处于上行/下行状态时,到达新的楼层时(本次循环开始),每次循环检查是否需要有人进出,根据载人列表、请求列表及当前运行状态判断出接下来的状态,如果是上行/下行,沉睡1s作为上行/下行一层楼的时间。算法的特征是,先来先服务,在上行/下行过程中尽可能接到或者放出更多的人,在上行/下行过程中只接受与电梯运行方向一致的人。

​ 代码如下:

import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
/*
从文件中读入输入命令及参数
*/
public class Elevator {
    private static List<EleInfo> infoList = new LinkedList<>();

    public static void main(String[] args) throws FileNotFoundException {
        start();
        new EleRunner(infoList).start();
    }

    public static void start() throws FileNotFoundException {
        int minFloor = 0;
        int maxFloor = 0;
        boolean started = false;
        boolean inputValid = false;
        Scanner in = new Scanner(
                new FileInputStream("/Users/macbook/programming/Java/leetcode/src/com/test/input.txt"),"UTF-8");
        PrintWriter out = new PrintWriter(
                new FileOutputStream("/Users/macbook/programming/Java/leetcode/src/com/test/log.txt",true),true);
        while(!inputValid) {
            out.println("电梯模拟运行开始,请输入参数(最低楼层,最高楼层):");
            try {
                minFloor = Integer.parseInt(in.next());
                maxFloor = Integer.parseInt(in.next());
                inputValid = true;
            } catch (Exception e) {
                System.out.println("输入异常!");
            }
        }

        while(true) {
            out.println("请输入命令(up/down/stop/start):");
            String cmd = in.next();
            if(started && cmd.equals("start")) {
                //已经开始但输入命令仍是start, 报错
                System.out.println("已经开始,不能再输入start!");
                continue;
            }
            if(!started && !cmd.equals("start")) {
                //没有开始但是输入命令不是start,报错
                out.println("请输入start开始!");
                continue;
            }
            if (cmd.equals("start")) {//开始
                started = true;
                infoList.add(new EleInfo(null, minFloor, maxFloor, "start"));
            } else if (cmd.equals("stop")) {//结束,跳出循环
                infoList.add(new EleInfo(null, 0, 0, "stop"));
                break;
            } else if(cmd.equals("up") || cmd.equals("down")) {
                String name = in.next();
                try {
                    int curFloor = Integer.parseInt(in.next());
                    int targetFloor = Integer.parseInt(in.next());
                    if (curFloor>=minFloor&&curFloor<=maxFloor&&targetFloor>=minFloor
                            &&targetFloor<=maxFloor&&targetFloor!=curFloor) {
                        if((cmd.equals("up")&&curFloor>=targetFloor) || (cmd.equals("down")&&curFloor<=targetFloor)) {
                            out.println("命令与输入楼层不匹配");
                        } else if(curFloor==targetFloor) {
                            out.println("目标楼层与当前楼层不一致!");
                        } else if(!isNameDuplicated(name)) {
                            out.println("人名重复!");
                        } else {//一切输入合法
                            infoList.add(new EleInfo(name, curFloor, targetFloor, cmd));
                        }
                    } else {
                        if(curFloor < minFloor || curFloor > maxFloor) {
                            out.println("当前楼层不合法!");
                        }
                        if(targetFloor < minFloor || targetFloor > maxFloor) {
                            out.println("目标楼层不合法!");
                        }
                        if(targetFloor==curFloor) {
                            out.println("当前楼层与目标楼层不能相同!");
                        }
                    }
                } catch (Exception e) {
                    out.println("输入楼层异常!");
                }
            } else {
                out.println("输入命令出错!");
            }

        }
        in.close();
    }
  
  private boolean isNameDuplicated(String name) {
    for(EleInfo e:infoList) {
      if(e.name.equals(name)) return true;
    }
  }
}

class EleInfo {
    String name;
    int curFloor;
    int targetFloor;
    String cmd;

    public EleInfo(String name, int curFloor, int targetFloor, String cmd) {
        this.name = name;
        this.curFloor = curFloor;
        this.targetFloor = targetFloor;
        this.cmd = cmd;
    }
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.*;

/*
电梯运行过程状态变化
*/
public class EleRunner {

    private List<EleInfo> requestList;
    private List<EleInfo> inElevatorList = new LinkedList<>();
    PrintWriter out;
    private ElevatorState state = ElevatorState.WAIT;
    private int curFloor = 0;
    private boolean started = false;
    private boolean stop = false;
    public EleRunner(List<EleInfo> infoList) throws FileNotFoundException {
        this.requestList = infoList;
        out = new PrintWriter(new FileOutputStream("/Users/macbook/programming/Java/leetcode/src/com/test/output.txt",true),true);
    }
    public void start() {
        while(true) {
            if(requestList.isEmpty()) continue;
            while(started) {
                if(requestList.isEmpty()) {
                    state = ElevatorState.WAIT;
                    continue;
                }
                if(requestList.size()==1 && inElevatorList.isEmpty() && requestList.get(0).cmd.equals("stop")) {
                    out.println("电梯停止运行!");
                    requestList.remove(0);
                    started = false;
                    stop = true;
                    break;
                }
                switch(state) {
                    case WAIT:
                        waitProc();
                        break;
                    case UP:
                        upProc();
                        break;
                    case DOWN:
                        downProc();
                        break;
                    default:
                        throw new IllegalArgumentException();
                }

                if(!requestList.isEmpty()) personIn();//状态更新,可能还可以有人进来
                if(state==ElevatorState.UP || state==ElevatorState.DOWN) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    curFloor = (state==ElevatorState.UP)?(curFloor+1):(curFloor-1);
                    String stateStr = (state==ElevatorState.UP)?"上升":"下降";
                    out.println("电梯到达"+curFloor+"楼,处于"+stateStr);
                }
            }
            if(stop) break;
            if(requestList.get(0).cmd.equals("start")) {
                started = true;
                curFloor = requestList.get(0).curFloor;
                out.println("电梯启动!");
                requestList.remove(0);
            }
        }
    }

    private void waitProc() {
        if(requestList.isEmpty()&&inElevatorList.isEmpty()) return;
        else {
            //没有请求但是电梯还载着人
            if(!requestList.isEmpty()) personIn();
            if(!inElevatorList.isEmpty()) personOut();
            if(!inElevatorList.isEmpty()) {
                state = inElevatorList.get(0).targetFloor > curFloor ? state = ElevatorState.UP:ElevatorState.DOWN;
            } else if(isOnlyStopReq()){
                state = ElevatorState.WAIT;
                out.println("电梯处于等待状态");
            } else if(!requestList.isEmpty()){
                if(!requestList.get(0).cmd.equals("stop"))
                    state = requestList.get(0).curFloor > curFloor ? state = ElevatorState.UP:ElevatorState.DOWN;
            }
        }
    }

    private void upProc() {
        if(requestList.isEmpty()&&inElevatorList.isEmpty()) {
            state = ElevatorState.WAIT;
        } else {
            if(!requestList.isEmpty()) personIn();//请求队列不空,看是否可以进人
            if(!inElevatorList.isEmpty()) personOut();//在电梯队列不空,看是否可以放人
            if(!inElevatorList.isEmpty()) {
                for(EleInfo e:inElevatorList) {
                    if(e.targetFloor > curFloor) return;
                }
                state = ElevatorState.DOWN;
            } else if(isOnlyStopReq()){
                state = ElevatorState.WAIT;
                out.println("电梯处于等待状态");
            } else if(!requestList.isEmpty()){
                for(EleInfo e:requestList) {
                    if(!e.cmd.equals("stop")&&e.curFloor > curFloor) return;
                }
                state = ElevatorState.DOWN;
            }
        }
    }

    private void downProc() {
        if(requestList.isEmpty()&&inElevatorList.isEmpty()) {
            state = ElevatorState.WAIT;
            out.println("电梯处于等待状态");
        } else {
            if(!requestList.isEmpty()) personIn();
            if(!inElevatorList.isEmpty()) personOut();
            if(!inElevatorList.isEmpty()) {
                for(EleInfo e:inElevatorList) {
                    if(e.targetFloor < curFloor) return;
                }
                state = ElevatorState.UP;
            } else if(isOnlyStopReq()){
                state = ElevatorState.WAIT;
                out.println("电梯处于等待状态");

            } else if(!requestList.isEmpty()){
                for(EleInfo e:requestList) {
                    if(!e.cmd.equals("stop")&&e.curFloor < curFloor) return;
                }
                state = ElevatorState.UP;
            }
        }
    }

    private void personIn() {
        Iterator<EleInfo> iterator = requestList.iterator();
        while(iterator.hasNext()) {//将curFloor等于电梯curFloor的请求删除,并放入inElevatorList中
            EleInfo e = iterator.next();
            if(e.curFloor==curFloor&&(state==ElevatorState.UP?(e.cmd.equals("up")):e.cmd.equals("down"))) {
                out.println(e.name+"在"+curFloor+"楼进电梯了!");
                iterator.remove();
                inElevatorList.add(e);
            }
        }
    }
    private void personOut() {
        Iterator<EleInfo> iterator = inElevatorList.iterator();
        while(iterator.hasNext()) {//首先把在电梯上目标楼层是当前楼层的人放出
            EleInfo e = iterator.next();
            if(e.targetFloor == curFloor) {
                out.println(e.name+"在"+curFloor+"楼出电梯了!");
                iterator.remove();
            }
        }
    }
    private boolean isOnlyStopReq() {
        return requestList.size()==1&&requestList.get(0).cmd.equals("stop");
    }

}


enum ElevatorState {
    WAIT,
    UP,
    DOWN
}


输入示例:

1 20
start
up
hjx 2 10
down
hyk 6 2
up
hyk1 1 8
down
hjx2 15 2
stop

输出结果:

电梯启动!
hyk1在1楼进电梯了!
电梯到达2楼,处于上升
hjx在2楼进电梯了!
电梯到达3楼,处于上升
电梯到达4楼,处于上升
电梯到达5楼,处于上升
电梯到达6楼,处于上升
电梯到达7楼,处于上升
电梯到达8楼,处于上升
hyk1在8楼出电梯了!
电梯到达9楼,处于上升
电梯到达10楼,处于上升
hjx在10楼出电梯了!
电梯到达11楼,处于上升
电梯到达12楼,处于上升
电梯到达13楼,处于上升
电梯到达14楼,处于上升
电梯到达15楼,处于上升
hjx2在15楼进电梯了!
电梯到达14楼,处于下降
电梯到达13楼,处于下降
电梯到达12楼,处于下降
电梯到达11楼,处于下降
电梯到达10楼,处于下降
电梯到达9楼,处于下降
电梯到达8楼,处于下降
电梯到达7楼,处于下降
电梯到达6楼,处于下降
hyk在6楼进电梯了!
电梯到达5楼,处于下降
电梯到达4楼,处于下降
电梯到达3楼,处于下降
电梯到达2楼,处于下降
hjx2在2楼出电梯了!
hyk在2楼出电梯了!
电梯处于等待状态
电梯停止运行!

可以观察一下输入的记录和电梯运行的结果,还是挺符合生活习惯的。

相关文章

  • 电梯运行程序模拟

    ​ 日常生活中,大家都坐过电梯,有时候会想想电梯在每个人按下键之后是怎么运行的呢?这是个看起来似乎简单但想清楚...

  • 模块1:“Hello World” - 运行程序

    运行程序 在开发阶段,程序可以运行在模拟器上,也可以运行在实机上。 模拟器运行模拟器即在桌面电脑上创建一台虚拟的A...

  • Java模拟电梯系统

    介绍: 用Java编写对的模拟电梯上下楼。 运行截图: 初始化界面 电梯进行上楼,输入3 5 -1 电梯下楼,输入...

  • 获取小程序源码

    安装node 下载夜神模拟器(开启root) 在模拟器下载 微信 然后运行微信,并运行起来想要破解的小程序 在模拟...

  • 关于Reveal Are you trying to load

    今天使用Reveal的时候,遇到一个错误,就是在模拟器上面运行程序,每次运行程序,程序都无法唤起,程序也没有报错,...

  • 日常生活中的产品思考

    ​ 有人说,每天上下班乘电梯,没有思考过电梯调度算法的程序猿不是好的程序猿,同理,没有归纳过电梯运行规则的产品汪也...

  • iOS调试问题

    程序调试 调用堆栈(call stack) -- 实战演练 .m文件中: 运行结果(Xcode模拟器) 在模拟器中...

  • Android模拟器运行程序INSTALL_FAILED_NO_

    问题描述 模拟器运行程序爆出如下错误: The application could not be installe...

  • 网易MuMu模拟器连接不上Android Studio

    近期开发一个项目,折腾了好久,编写完程序后,真机上运行没有异常,而在MuMu模拟器上运行,程序总是中断(MuMu模...

  • Android Studio卡在“Waiting for tar

    运行程序时一直卡在waiting for target device to come online,明明模拟器已经...

网友评论

      本文标题:电梯运行程序模拟

      本文链接:https://www.haomeiwen.com/subject/qbwwkctx.html