停车场管理系统

开发

 

以下为停车场管理系统的代码:

 

首先定义Car类,记录车辆信息:

 

```java

public class Car {

    private String plateNumber;  // 车牌号

    private long enterTime;  // 进入停车场时间

    private long exitTime;  // 离开停车场时间

 

    public Car(String plateNumber, long enterTime) {

        this.plateNumber = plateNumber;

        this.enterTime = enterTime;

    }

 

    public String getPlateNumber() {

        return plateNumber;

    }

 

    public long getEnterTime() {

        return enterTime;

    }

 

    public long getExitTime() {

        return exitTime;

    }

 

    public void setExitTime(long exitTime) {

        this.exitTime = exitTime;

    }

}

```

 

定义一个接口,包含小型车库的基本操作:

 

```java

public interface CarGarage {

    boolean isFull();  // 是否已满

    void addCar(Car car);  // 将车辆加入车库

    Car removeCar(String plateNumber);  // 将车辆从车库中移除

    boolean contains(String plateNumber);  // 判断车库中是否包含指定车辆

    int getSize();  // 返回车库当前的车辆数量

}

```

 

实现CarGarage接口,使用散列表(Node)进行模拟:

 

```java

public class CarGarageImpl implements CarGarage {

    private static final int GARAGE_CAPACITY = 5;  // 小型车库的容量

    private Map garageMap = new HashMap<>();

 

    // 散列表节点类

    private class Node {

        Car car;

        Node next;

 

        Node(Car car, Node next) {

            this.car = car;

            this.next = next;

        }

    }

 

    // 获取指定车辆应该存储的散列表下标

    private int getIndex(String plateNumber) {

        return Math.abs(plateNumber.hashCode()) % GARAGE_CAPACITY;

    }

 

    @Override

    public boolean isFull() {

        int size = 0;

        for (Node node : garageMap.values()) {

            for (; node != null; node = node.next) {

                size++;

            }

        }

        return size == GARAGE_CAPACITY;

    }

 

    @Override

    public void addCar(Car car) {

        int index = getIndex(car.getPlateNumber());

        Node node = garageMap.get(index);

        garageMap.put(index, new Node(car, node));

    }

 

    @Override

    public Car removeCar(String plateNumber) {

        int index = getIndex(plateNumber);

        Node node = garageMap.get(index);

        Node prev = null;

 

        while (node != null) {

            if (node.car.getPlateNumber().equals(plateNumber)) {

                if (prev == null) {

                    garageMap.put(index, node.next);

                } else {

                    prev.next = node.next;

                }

                return node.car;

            }

            prev = node;

            node = node.next;

        }

        return null;

    }

 

    @Override

    public boolean contains(String plateNumber) {

        int index = getIndex(plateNumber);

        Node node = garageMap.get(index);

 

        while (node != null) {

            if (node.car.getPlateNumber().equals(plateNumber)) {

                return true;

            }

            node = node.next;

        }

        return false;

    }

 

    @Override

    public int getSize() {

        int size = 0;

        for (Node node : garageMap.values()) {

            for (; node != null; node = node.next) {

                size++;

            }

        }

        return size;

    }

}

```

 

定义一个接口,包含停车场的基本操作:

 

```java

public interface ParkingLot {

    void enter(Car car);  // 车辆进场

    void exit(Car car);  // 车辆出场

    int getEmptySpotCount();  // 返回停车场空余车位数量

}

```

 

实现ParkingLot接口,使用队列存储车辆排队的情况,每五个车位使用一个小型车库进行模拟:

 

```java

public class ParkingLotImpl implements ParkingLot {

    private static final int PARKING_LOT_CAPACITY = 100;  // 停车场容量

    private static final int GARAGE_COUNT = PARKING_LOT_CAPACITY / 5;  // 小型车库数量

    private static final double PRICE_PER_15_MINUTE = 0.5;  // 普通车辆停车价格:0.5元/15分钟

    private static final double NIGHT_PRICE_PER_HOUR = 1;  // 夜间车辆停车价格:1元/小时

    private static final long NIGHT_START_TIME = 22 * 3600 * 1000;  // 夜间计费开始时间:22点

    private static final long NIGHT_END_TIME = 6 * 3600 * 1000;  // 夜间计费结束时间:6点

 

    private int emptySpotCount = PARKING_LOT_CAPACITY;  // 停车场空余车位数量

    private Queue[] entranceQueues;  // 入口队列数组

    private Queue exitQueue = new LinkedList<>();  // 出口排队队列

    private CarGarage[] garages;  // 小型车库数组

 

    public ParkingLotImpl(int entranceCount) {

        entranceQueues = new Queue[entranceCount];

        for (int i = 0; i < entranceCount; i++) {

            entranceQueues[i] = new LinkedList<>();

        }

 

        garages = new CarGarage[GARAGE_COUNT];

        for (int i = 0; i < garages.length; i++) {

            garages[i] = new CarGarageImpl();

        }

    }

 

    @Override

    public void enter(Car car) {

        int emptyGarageIndex = -1;

        for (int i = 0; i < garages.length; i++) {

            if (!garages[i].isFull()) {

                emptyGarageIndex = i;

                break;

            }

        }

 

        if (emptyGarageIndex != -1) {

            garages[emptyGarageIndex].addCar(car);

            emptySpotCount--;

        } else {

            entranceQueues[0].offer(car); // 第一个入口就放排队

        }

    }

 

    private long getParkingTime(Car car) {

        return car.getExitTime() - car.getEnterTime();

    }

 

    private double calcPrice(long parkingTime) {

        if (parkingTime <= 15 * 60 * 1000) { // 普通车免费15分钟

            return 0;

        } else {

            double price = Math.ceil((double) parkingTime / (15 * 60 * 1000)) * PRICE_PER_15_MINUTE;

            // 夜间停车价格

            if (car.getEnterTime() < NIGHT_END_TIME || car.getEnterTime() >= NIGHT_START_TIME) {

                price += (double) Math.ceil((double) parkingTime / (60 * 60 * 1000)) * NIGHT_PRICE_PER_HOUR;

            }

            return price;

        }

    }

 

    @Override

    public void exit(Car car) {

        int garageIndex = -1;

        for (int i = 0; i < garages.length; i++) {

            if (garages[i].contains(car.getPlateNumber())) {

                garageIndex = i;

                break;

            }

        }

 

        if (garageIndex != -1) {

            Car removedCar = garages[garageIndex].removeCar(car.getPlateNumber());

            long parkingTime = removedCar.getExitTime() - removedCar.getEnterTime();

            double price = calcPrice(parkingTime);

            emptySpotCount++;

            System.out.println("离开了停车库,车牌号为" + removedCar.getPlateNumber() + ",停车时间为" + parkingTime +

                    "毫秒,需支付" + price + "元");

        } else {

            System.out.println("未找到车牌号为" + car.getPlateNumber() + "的车辆");

        }

    }

 

    @Override

    public int getEmptySpotCount() {

        return emptySpotCount;

    }

 

    // 模拟车辆进场

    public void simulateCarEnter() {

        for (Queue entranceQueue : entranceQueues) {

            if (entranceQueue.isEmpty()) {

                continue;

            }

 

            // 先检查是否有空车位,有的话直接入车库

            int emptyGarageIndex = -1;

            for (int i = 0; i < garages.length; i++) {

                if (!garages[i].isFull()) {

                    emptyGarageIndex = i;

                    break;

                }

            }

 

            // 没有空车位

            if (emptyGarageIndex == -1) {

                Car car = entranceQueue.peek();

                if (garages[0].contains(car.getPlateNumber())) {

                    entranceQueue.poll();  // 已在排队列中的车,直接取出

                } else {

                    entranceQueue.offer(car);  // 添加到排队队列的末尾等待下次取出

                }

            } else {

                Car car = entranceQueue.poll();

                garages[emptyGarageIndex].addCar(car);

                emptySpotCount--;

            }

        }

    }

 

    // 模拟车辆出场

    public void simulateCarExit() {

        if (exitQueue.isEmpty()) {

            return;

        }

 

        Car car = exitQueue.peek();

 

        // 夜间停车不允许从22点较晚离开22点较早

        if (car.getEnterTime() < NIGHT_END_TIME || car.getEnterTime() >= NIGHT_START_TIME) {

            if (System.currentTimeMillis() < NIGHT_START_TIME && car.getExitTime() >= NIGHT_START_TIME) {

                System.out.println("当前时间为夜间停车计费时间段内,不允许车牌号为" + car.getPlateNumber() + "的车辆现在离开停车场。");

                return;

            }

        }

 

        exitQueue.poll();

 

        Car removedCar;

        int garageIndex = -1;

        for (int i = 0; i < garages.length; i++) {

            if (garages[i].contains(car.getPlateNumber())) {

                garageIndex = i;

                break;

            }

        }

        if (garageIndex != -1) {

            removedCar = garages[garageIndex].removeCar(car.getPlateNumber());

            long parkingTime = removedCar.getExitTime() - removedCar.getEnterTime();

            double price = calcPrice(parkingTime);

            emptySpotCount++;

            System.out.println("离开了停车库,车牌号为" + removedCar.getPlateNumber() + ",停车时间为" + parkingTime +

                    "毫秒,需支付" + price + "元");

        } else {

            System.out.println("未找到车牌号为" + car.getPlateNumber() + "的车辆");

        }

    }

 

    // 获取下一个应该出场的车辆

    private Car getNextExitCar() {

        Car nextCar = null;

        long nextExitTime = Long.MAX_VALUE;

 

        for (CarGarage garage : garages) {

            for (Node node : ((CarGarageImpl) garage).garageMap.values()) {

                for (; node != null; node = node.next) {

                    Car car = node.car;

                    if (car.getExitTime() < nextExitTime) {

                        nextExitTime = car.getExitTime();

                        nextCar = car;

                    }

                }

            }

        }

 

        return nextCar;

    }

 

    // 模拟出场排队

    public void simulateExitQueue() {

        if (getEmptySpotCount() == PARKING_LOT_CAPACITY) {

            return;

        }

 

        while (exitQueue.size() < 1 && getNextExitCar() != null) {

            Car nextCar = getNextExitCar();

            exitQueue.offer(nextCar);

            long waitTime = nextCar.getExitTime() - System.currentTimeMillis();

            try {

                Thread.sleep(waitTime);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

    }

}

```

 

最后,可以使用以下方式模拟车辆进出停车场的情况:

 

```java

public static void main(String[] args) {

    ParkingLot parkingLot = new ParkingLotImpl(5);

    String[] plateNumbers = {"京A12345", "京A23456", "京A34567", "京A45678", "京A56789", "京A67890",

            "京B12345", "京B23456", "京B34567", "京B45678", "京B56789", "京B67890"};

    Random random = new Random();

 

    // 模拟车辆进入停车场

    Timer timer = new Timer();

    timer.scheduleAtFixedRate(new TimerTask() {

        @Override

        public void run() {

            Car car = new Car(plateNumbers[random.nextInt(12)], System.currentTimeMillis());

            parkingLot.enter(car);

        }

    }, 0, 500);

 

    // 模拟车辆出场

    timer.scheduleAtFixedRate(new TimerTask() {

        @Override

        public void run() {

            parkingLot.simulateExitQueue();

            parkingLot.simulateCarExit();

        }

    }, 0, 1000);

 

    // 模拟车辆进入小型车库

    timer.scheduleAtFixedRate(new TimerTask() {

        @Override

        public void run() {

            parkingLot.simulateCarEnter();

        }

    }, 0, 5000);

}

```

 

 

以下是 Python 代码示例,实现了停车场管理系统的大致功能:

 

```python

import time

from collections import deque

 

# 停车场

class ParkingLot:

    def __init__(self, num_entrances, num_exits, num_spaces):

        self.num_entrances = num_entrances

        self.num_exits = num_exits

        self.num_spaces = num_spaces

        self.entrance_queues = [deque() for _ in range(num_entrances)]

        self.spaces = [Space() for _ in range(num_spaces)]

        self.night_rate = 1  # 小型车夜间停车费用:1元/小时

 

    # 停车

    def park(self, car):

        # 获取可用车位

        space = self.get_empty_space()

        if space is not None:

            # 将车停入车位

            space.park(car)

        elif self.is_full():

            # 如果停车场已满,则车辆排队等候

            print(f"停车场已满,请{car}在入口处排队等候")

            self.entrance_queues[car.entrance].append(car)

        else:

            raise Exception("Invalid parking state")

 

    # 取车

    def unpark(self, car):

        space = self.find_space_by_car(car)

        if space is not None:

            duration = car.get_duration()

            fee = 0  # 停车费用

            if car.is_small:

                # 夜间停车费用

                hour = time.localtime(car.enter_time).tm_hour

                if hour >= 22 or hour < 6:

                    fee = self.night_rate * duration / 3600

            # 计算停车费用

            fee += duration // 900 * 0.5

            print(f"{car}停车时长为{duration//60}分钟,停车费用为{fee:.2f}元")

            space.unpark(car)

            # 检查排队等候的车辆

            self.check_waiting_cars()

        else:

            raise Exception(f"{car}不在停车场内")

 

    # 获取可用车位

    def get_empty_space(self):

        for space in self.spaces:

            if not space.is_occupied():

                return space

        return None

 

    # 根据车牌号查找车位

    def find_space_by_car(self, car):

        for space in self.spaces:

            if space.car == car:

                return space

        return None

 

    # 停车场是否已满

    def is_full(self):

        for space in self.spaces:

            if not space.is_occupied():

                return False

        return True

 

    # 检查排队等候的车辆

    def check_waiting_cars(self):

        for i in range(self.num_entrances):

            if len(self.entrance_queues[i]) > 0:

                car = self.entrance_queues[i][0]

                space = self.get_empty_space()

                if space is not None:

                    self.entrance_queues[i].popleft()

                    self.park(car)

                    print(f"{car}入场成功")

 

 

# 车位

class Space:

    def __init__(self):

        self.car = None

 

    # 判断车位是否被占用

    def is_occupied(self):

        return self.car is not None

 

    # 停车

    def park(self, car):

        self.car = car

        car.enter_time = time.time()

 

    # 取车

    def unpark(self, car):

        self.car = None

 

 

# 车辆

class Car:

    def __init__(self, plate, entrance, is_small):

        self.plate = plate  # 车牌号码

        self.entrance = entrance  # 入口编号

        self.is_small = is_small  # 是否小型车

        self.enter_time = None  # 进场时间

 

    # 获取停车时长,返回秒数

    def get_duration(self):

        if self.enter_time is not None:

            return time.time() - self.enter_time

        else:

            return -1

 

    def __str__(self):

        return self.plate

 

 

if __name__ == '__main__':

    lot = ParkingLot(2, 2, 25)

    for i in range(80):

        is_small = i % 5 == 0  # 每5个车位是一个小型车库

        car = Car(f"京A{i:02d}", i % 2, is_small)

        if i == 40:

            lot.unpark(car)  # 取走一辆不存在的车

        else:

            lot.park(car)

        time.sleep(0.1)  # 模拟每隔一段时间有车进入或离开停车场

```

你可能感兴趣的:(散列表,数据结构)