【学校实验】停车场问题:设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。

停车场问题

  • 问题描述
  • 测试数据
  • 基本要求
  • 实现提示
  • 代码实现
    • 栈的实现
    • 队列的实现
    • 主函数的实现


问题描述

设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。


测试数据

设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3, 20),(‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。

每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,其中,‘A’表示到达;‘D’表示离去,‘E’表示输入结束。

基本要求

以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。栈以顺序结构实现,队列以链表实现。


实现提示

需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也用顺序存储结构实现。输入数据按到达或离去的时刻有序。栈中每个元素表示一辆汽车,包含两个数据项:汽车的牌照号码和进入停车场的时刻。

代码实现

栈的实现

import java.util.Iterator;
public class Queue_List<T> implements Iterable{
    //存储元素的数组
    private T[] eles;
    //记录当前栈中的元素个数
    private int N;

    //构造方法
    public Queue_List(int capacity){
        //初始化数组
        this.eles=(T[])new Object[capacity];
        //初始化长度
        this.N=0;
    }

    //将一个栈置为空
    public void clear(){
        this.N=0;
    }

    //判断当前栈是否为空
    public boolean isEmpty(){
        return N==0;
    }

    //获取栈的元素个数
    public int size(){
        return N;
    }

    //获取指定位置的元素
    public T get(int i){
        return eles[i];
    }

    //判断当前栈是否已满
    public boolean isFull(){ return N == eles.length; }

    //把t元素压入栈
    public void push(T t){
        if(N == eles.length){
            System.out.println("栈已满");
        }
        else
            eles[N++]=t;
    }


    //弹出栈顶元素
    public T pop(){
        //记录索引i处的值
        T current = eles[N-1];
        //元素个数-1
        N--;
        return current;
    }

    //遍历栈
    @Override
    public Iterator<T> iterator() {
        return new SIterator();
    }

    private class SIterator implements Iterator{

        private int cusor;
        public SIterator(){
            this.cusor = 0;
        }
        @Override
        public boolean hasNext() {//判断容器还有没有下一个元素
            return cusor < N;
        }

        @Override
        public Object next() {//获取当前容器下一个元素
            return eles[cusor++];
        }
    }
}

队列的实现


//队列结构

import java.util.Iterator;

public class Queue<T> implements Iterable<T>{
    //记录首结点
    private Node head;
    //记录最后一个结点
    private Node last;
    //记录队列中元素的个数
    private int N;


    private class Node{
        public T item;
        public Node next;

        public Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
    }
    public Queue() {
        this.head = new Node(null,null);
        this.last=null;
        this.N=0;
    }

    //判断队列是否为空
    public boolean isEmpty(){
        return N==0;
    }

    //返回队列中元素的个数
    public int size(){
        return N;
    }

    //向队列中插入元素t
    public void enqueue(T t){

        if (last==null){
            //当前尾结点last为null
            last= new Node(t,null);
            head.next=last;
        }else {
            //当前尾结点last不为null
            Node oldLast = last;
            last = new Node(t, null);
            oldLast.next=last;
        }

        //元素个数+1
        N++;
    }

    //从队列中拿出一个元素
    public T dequeue(){
        if (isEmpty()){
            return null;
        }

        Node oldFirst= head.next;
        head.next=oldFirst.next;
        N--;

        //因为出队列其实是在删除元素,因此如果队列中的元素被删除完了,需要重置last=null;

        if (isEmpty()){
            last=null;
        }
        return oldFirst.item;
    }


    @Override
    public Iterator<T> iterator() {
        return new QIterator();
    }

    private class QIterator implements Iterator{
        private Node n;

        public QIterator(){
            this.n=head;
        }
        @Override
        public boolean hasNext() {
            return n.next!=null;
        }

        @Override
        public Object next() {
            n = n.next;
            return n.item;
        }
    }
}

主函数的实现

import java.util.Scanner;
/*
【问题描述】
设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内
按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场
的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,
则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出
车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离
开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。

【测试数据】
设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3, 20),
 (‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。
 每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,
 其中,‘A’表示到达;‘D’表示离去,‘E’表示输入结束。

【基本要求】
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。每一组
输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组
输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若
是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。栈以
顺序结构实现,队列以链表实现。

【实现提示】
需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也用顺序存储结构实现。输
入数据按到达或离去的时刻有序。栈中每个元素表示一辆汽车,包含两个数据项:汽车的牌照号码和进
入停车场的时刻。
 */
/*
 * 栈 与 队列 两个栈 一个充当停车场 另一个保存出栈的元素顺序 队列用于存放排队的车
 * 另外每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻
 */
public class Car_Park {
    public static void main(String[] args) {
        Queue<String> sta = new Queue<>();//队列用于存储排队的车
        Queue_List<String> queue01 = new Queue_List<>(2); //栈1用于充当停车场
        Queue_List<String> queue02 = new Queue_List<>(2);//栈2用于保存出栈的元素顺序

        System.out.println("请输入停车场可以停放多少部车");
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

        System.out.println("您的数据总个数");
        int num = 0;
        num = sc.nextInt();

        System.out.println("请依次输入您的数据");

        //二维数组存储录入的数据
        String[][] Array = new String[num][3];
        for (int i = 0; i < num; i++) {
            for (int j = 0; j < 3; j++) {
                Array[i][j] = sc.next();
            }
        }

        //遍历二维数组遇到A则入栈,遇到D则出栈
        int loctionQueue = 0;
        int loctionStack = 0;
        //
        for (int i = 0; i < num; i++) {
            for (int j = 0; j < 3; j++) {
                switch (Array[i][j]) {

                    case "A"://A入栈
                        if (queue01.isFull()) {//栈已满将元素放入队列中排队
                            sta.enqueue(Array[i][1]);
                            System.out.println(Array[i][1] + "号车在第" + loctionStack + "号等车位");
                            loctionStack++;

                        }
                        if (!queue01.isFull()) {
                            queue01.push(Array[i][1]);//栈未满进行压栈操作
                            System.out.println(Array[i][1] + "号车在第" + loctionQueue + "号车位");
                            loctionQueue++;
                        }
                        break;

                    case "D"://D出栈

                        //Array[i][2]是汽车出栈的编号,现用栈里的编号与出栈编号比较 相同则出栈不相同则保存到栈2里
                        String chuzhan = null;//记录弹出栈的元素值(汽车的编号)
                        int stime = 1;//记录初始时间
                        int ftime = 0;//记录结束时间
                        int time = 0;//记录时间差

                        while (!queue01.isEmpty()) {//提取全部元素,符合要求的直接提取,不符合存入栈2
                            String temp = queue01.pop();
                            String temp1 = Array[i][1];
                            if (!temp.equals(temp1)) {//不符合要求放入栈2
                                queue02.push(temp);
                            }
                            if (temp.equals(temp1)) {//符合要求提取出来
                                chuzhan = temp;//将弹出元素赋值变量chuzhan

                                //求时间
                                int i2 = Integer.parseInt(Array[i][2]);//字符串转int

                                ftime = i2;//结束时间
                            }
                        }

                        System.out.println("栈是否为空:" + queue01.isEmpty());
                        //再次遍历数组找到编号第一次出现的地方记录1号位的时间
                        label:for (int k = 0; k < num; k++) {
                            for (int l = 0; l < 3; l++) {
                                if (Array[k][1].equals(chuzhan)) {//找出弹出的汽车编号第一次出现的地方 记录次数组的时间
                                    int ii = Integer.parseInt(Array[k][2]);//字符串转int
                                    stime = ii;
                                    break label;
                                }
                            }
                        }


                        //计算停车时间

                        time = ftime - stime;
                        System.out.println(chuzhan + "号车离开   " + chuzhan +"号车的停留时间为" + time);

                        System.out.println("结束时间为: " + ftime);
                        System.out.println("初始时间为: " + stime);

                        //弹栈后,栈2和队列里面的元素进栈,弹一进一
                        loctionQueue = 0;//车位重置
                        System.out.println("-------------------------");
                        while (!queue02.isEmpty()) {
                            String temp = queue02.pop();
                            queue01.push(temp);
                            System.out.println(temp + "号车在第" + loctionQueue + "号车位");
                            loctionQueue++;
                        }

                        while (!queue01.isFull()) {
                            if (!sta.isEmpty()) {
                                String temp = sta.dequeue();
                                queue01.push(temp);
                                System.out.println(temp + "号车在第" + loctionQueue + "号车位");
                                loctionQueue++;


                                //重置初始时间
                                label02:for (int k = 0; k < num; k++) {
                                    for (int l = 0; l < 3; l++) {
                                        if (Array[k][1].equals(temp)) {
                                            Array[k][2] = Array[i][2];
                                            break label02;
                                        }
                                    }
                                }

                            }
                            if (sta.isEmpty()){
                                break;
                            }
                        }
                        break;
                    case "E":
                        break;
                }
            }
        }
    }
}


/*
代码问题总结:
1.键盘录入动态数组的元素(未解决)
2.录入总体数据,每个数据中又分数据小块,使用二维数组
3.数组的索引从0开始
4.二维数组[x][y] x代表哪一个一维数组 y代表这个一维数组的哪一个元素
5.对于String来说,== 比较的是地址, equals比较的是字符串的类型
6.String转int int ii = Integer.parseInt(String类型数据);
7.跳出多层循环 利用标签变量 在头循环前声明标签 需要跳出循环时break 标签;
 */

你可能感兴趣的:(队列,数据结构,java,链表,栈)