停车管理系统

停车场管理系统的设计与实现

设停车场是一个可以停放n辆汽车的南北方向的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次从北向南排列(大门在最南端,最先到达的第一辆车停放在车辆的最北端)。若车场内已停满n辆车,那么后来的车只能在门外的便道上等候。一旦停车场内某辆车要离开,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,则排在便道的第一辆车即可开入,其他让路的车辆再按原次序进入车场。试为停车场编制按上述进行管理的模拟程序,要求程序输出车辆到达及离开后停车场与便道的停车情况。初步分析:由于这个停车场只有一个大门,当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,先进停车场的后退出,后进车场的先退出,符合栈的“后进先出,先进后出”的操作特点,因此,可以用一个栈来模拟停车场。而当停车场满后,继续到来的其他车辆只能停在便道上,根据便道停车的特点,先排队的车辆先离开便道进入停车场,符合队列的“先进先出,后进后出”的操作特点,因此,可以用一个队列来模拟便道。排在停车场中间的车辆可以提出离开停车场,并且停车场内在要离开车辆之后才到达的其他车辆,都必须先离开停车场为它让路,然后这些车辆依原来的次序重新进入停车场,因此在前面已设的一个栈和一个队列的基础上,还需要有一个临时的地方保存为了让路离开停车场的车辆,这个临时停放让路车辆的地方也具备栈的性质。总之,此系统涉及到二个栈和一个队列。请根据上述描述,设计出相应的系统。#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <stdbool.h>

#define MAX_PARKING 5 // 停车场容量

#define MAX_WAITING 10 // 便道容量

#define PRICE_PER_SEC 1.0 // 每秒费用(1元/秒)

 

//数据结构定义 

typedef struct {

    char plate[10]; // 车牌号

    time_t enter_time;// 进入时间

} Vehicle;

 

typedef struct {

    Vehicle data[MAX_PARKING];

    int top;

} ParkingStack;

 

typedef struct {

    Vehicle data[MAX_WAITING];

    int front, rear; 

} WaitingQueue;

// 临时栈 

typedef struct {

    Vehicle data[MAX_PARKING];

    int top;

} TempStack;

//函数声明 

bool isQueueEmpty(WaitingQueue *wq);//判断便道队列是否为空

bool isParkingFull(ParkingStack *ps);//判断停车场是否已满,从便道补充车辆用到 

//初始化 

void initParking(ParkingStack *ps);

void initWaiting(WaitingQueue *wq);

void initTemp(TempStack *ts);

//核心功能 

void vehicleArrival(ParkingStack *ps, WaitingQueue *wq);//处理车辆到达

void vehicleDeparture(ParkingStack *ps, WaitingQueue *wq);//处理车辆离开

void searchVehicle(ParkingStack *ps, WaitingQueue *wq);//查询车辆位置的函数

//显示系统状态

void displaySystem(ParkingStack *ps, WaitingQueue *wq);

//打印车辆信息

void printVehicle(Vehicle v, bool show_time);

//计费 

double calculateFee(time_t enter);

//暂停程序,等待用户按回车键继续的函数

void pressEnterToContinue();

//栈操作

bool pushParking(ParkingStack *ps, Vehicle v);

Vehicle popParking(ParkingStack *ps);

bool pushTemp(TempStack *ts, Vehicle v);

Vehicle popTemp(TempStack *ts);

//队列操作

bool enqueue(WaitingQueue *wq, Vehicle v);

Vehicle dequeue(WaitingQueue *wq);

 

//主程序

int main() {

    ParkingStack parking;

    WaitingQueue waiting;

    TempStack temp;

 

    initParking(&parking);

    initWaiting(&waiting);

    initTemp(&temp);

 

    int choice;

    while (1) {

        system("cls");//调用系统命令清屏

        displaySystem(&parking, &waiting);

 

        printf("\n╔════════════════ 操作菜单 ════════════════╗\n");

        printf("║ 1. 车辆到达 2. 车辆离开 3. 查找车辆 ║\n");

        printf("║ 4. 退出系统 ║\n");

        printf("╚══════════════════════════════════════════╝\n");

        printf("请选择操作(1 - 4): ");

 

        if (scanf("%d", &choice) != 1) {

            while (getchar() != '\n'); // 清除无效输入

            continue;

             // 跳过本次循环,重新显示菜单等待用户输入

        }

 

        switch (choice) {

            case 1:

                vehicleArrival(&parking, &waiting);

                break;

            case 2:

                vehicleDeparture(&parking, &waiting);

                break;

            case 3:

                searchVehicle(&parking, &waiting);

                break;

            case 4:

                printf("\n感谢使用停车场管理系统!\n");

                exit(0);

            default:

                printf("无效选项,请重新输入!\n");

        }

        pressEnterToContinue();

    }

    return 0;

}

 

//初始化函数

void initParking(ParkingStack *ps) {

    ps->top = -1;//栈空 

    memset(ps->data, 0, sizeof(ps->data));

}

 

void initWaiting(WaitingQueue *wq) {

    wq->front = -1;

    wq->rear = -1;

    memset(wq->data, 0, sizeof(wq->data));//将便道队列 wq 中的车辆信息数组 data 的所有元素初始化为 0

}

 

void initTemp(TempStack *ts) {

    ts->top = -1;

    memset(ts->data, 0, sizeof(ts->data));

}

 

//车辆到达处理 

void vehicleArrival(ParkingStack *ps, WaitingQueue *wq) {

    Vehicle new_vehicle;

    printf("\n请输入车牌号: ");

    scanf("%9s", new_vehicle.plate);

    new_vehicle.enter_time = time(NULL);//返回系统当前时间 

 

    // 尝试进入停车场(入栈) 

    if (pushParking(ps, new_vehicle)) {

        printf("车辆 %s 已停入停车场(时间:%s", new_vehicle.plate, ctime(&new_vehicle.enter_time));//将 long类型的时间戳转换为一个可读的本地时间字符串,格式一般为 Www Mmm dd hh:mm:ss yyyy

    } else {

        // 停车场已满,进入便道

        if (enqueue(wq, new_vehicle)) {

            printf("车辆 %s 进入便道等待(时间:%s", new_vehicle.plate, ctime(&new_vehicle.enter_time));

        } else {

            printf("便道已满,无法接收更多车辆!\n");

        }

    }

}

//车辆离开处理

void vehicleDeparture(ParkingStack *ps, WaitingQueue *wq) {

    char target_plate[10];

    printf("\n请输入要离开的车牌号: ");

    scanf("%9s", target_plate);

 

    TempStack temp_stack;

    initTemp(&temp_stack);

    bool found = false;

    time_t exit_time = time(NULL);

 

    //第一阶段:查找目标车辆

    while (ps->top != -1) {

        Vehicle current = popParking(ps);

        if (strcmp(current.plate, target_plate) == 0) {

            found = true;

            double fee = calculateFee(current.enter_time);

            printf("\n车辆 %s 离开成功!\n", target_plate);

            printf("停留时间: %.0f秒\n费用合计: %.2f元\n", difftime(exit_time, current.enter_time), fee);

            break;

        }

        pushTemp(&temp_stack, current);

    }

    //第二阶段:恢复车辆顺序

    if (found) {

        //将临时栈中的车辆重新压回停车场栈

        while (temp_stack.top != -1) {

            pushParking(ps, popTemp(&temp_stack));

        }

        //从便道补充车辆

        if (!isQueueEmpty(wq) && !isParkingFull(ps)) {

            Vehicle next = dequeue(wq);//出队 

            pushParking(ps, next);//入停车场栈 

            printf("便道车辆 %s 已进入停车场\n", next.plate);

        }

    } else {

        //未找到车辆,恢复原停车场

        while (temp_stack.top != -1) {

            pushParking(ps, popTemp(&temp_stack));

        }

        printf("未找到车牌号为 %s 的车辆!\n", target_plate);

    }

}

//车辆查询 

void searchVehicle(ParkingStack *ps, WaitingQueue *wq) {

    char target_plate[10];

    printf("\n请输入要查询的车牌号: ");

    scanf("%9s", target_plate);

    bool found = false;

    int position = 1;

 

//检查停车场

    for (int i = 0; i <= ps->top; i++, position++) {

        if (strcmp(ps->data[i].plate, target_plate) == 0) {

            printf("车辆 %s 位于停车场第%d位(进入时间:%s)", target_plate, position, ctime(&ps->data[i].enter_time));

            found = true;

            break;

        }

    }

 

//检查便道队列

    if (!found) {

        printf("\n检查便道队列...");

        //计算队列长度

        if (wq->front != -1) {

            int index = wq->front;

            int count = 1;

            while (index != wq->rear) {

                if (strcmp(wq->data[index].plate, target_plate) == 0) {

                    printf("\n车辆 %s 位于便道队列的第%d位", target_plate, count);

                    found = true;

                    break;

                }

                index++;

                count++;

            }

            // 检查队尾元素

            if (!found && strcmp(wq->data[wq->rear].plate, target_plate) == 0) {

                printf("\n车辆 %s 位于便道队列的第%d位", target_plate, count);

                found = true;

            }

        }

    }

 

    if (!found) {

        printf("\n未找到车辆 %s!\n", target_plate);

    }

}

//显示系统状态

void displaySystem(ParkingStack *ps, WaitingQueue *wq) {

    printf("\n══════════════ 当前系统状态 ══════════════\n");

 

    //显示停车场

    printf("\n停车场(%d/%d):\n", ps->top + 1, MAX_PARKING);

    if (ps->top == -1) {

        printf(" [空]\n");

    } else {

        for (int i = 0; i <= ps->top; i++) {

            printf(" 车位%d: ", i + 1);

            printVehicle(ps->data[i], true);

        }

    }

    //显示便道

    printf("\n便道队列(%d/%d):\n",

           (wq->front == -1) ? 0 : (wq->rear >= wq->front) ?

           (wq->rear - wq->front + 1) : (MAX_WAITING - wq->front + wq->rear + 1),

           MAX_WAITING);

    if (wq->front == -1) {

        printf(" [无车辆等待]\n");

    } else {

        int i = wq->front;

        do {

            printVehicle(wq->data[i], false);

            i = (i + 1) % MAX_WAITING;

        } while (i != (wq->rear + 1) % MAX_WAITING);//遍历完成条件 

    }

}

void printVehicle(Vehicle v, bool show_time) {

    printf("%s", v.plate);

    if (show_time) {

        printf(" (进入时间: %s)", ctime(&v.enter_time));

    } else {

        printf("\n");

    }

}

 

double calculateFee(time_t enter) {

    time_t now = time(NULL);

    return difftime(now, enter) * PRICE_PER_SEC;

}

 

void pressEnterToContinue() {

    printf("\n按Enter键继续...");

    while (getchar() != '\n');

    getchar();

}

 

//栈操作实现 

bool pushParking(ParkingStack *ps, Vehicle v) {

    if (ps->top >= MAX_PARKING - 1) return false;

    ps->data[++ps->top] = v;

    return true;

}

 

Vehicle popParking(ParkingStack *ps) {

    Vehicle empty_vehicle;

    strcpy(empty_vehicle.plate, "");

    empty_vehicle.enter_time = 0;

    if (ps->top == -1) return empty_vehicle;

    return ps->data[ps->top--];

}

 

bool pushTemp(TempStack *ts, Vehicle v) {

    if (ts->top >= MAX_PARKING - 1) return false;

    ts->data[++ts->top] = v;

    return true;

}

 

Vehicle popTemp(TempStack *ts) {

    Vehicle empty_vehicle;

    strcpy(empty_vehicle.plate, "");

    empty_vehicle.enter_time = 0;

    if (ts->top == -1) return empty_vehicle;

    return ts->data[ts->top--];

}

 

//队列操作实现

bool enqueue(WaitingQueue *wq, Vehicle v) {

    if ((wq->rear + 1) % MAX_WAITING == wq->front) return false;

 

    if (wq->front == -1) {

        wq->front = wq->rear = 0;

    } else {

        wq->rear = (wq->rear + 1) % MAX_WAITING;

    }

    wq->data[wq->rear] = v;//放入队尾 

    return true;

 

Vehicle dequeue(WaitingQueue *wq) {

    Vehicle empty_vehicle;

    strcpy(empty_vehicle.plate, "");

    empty_vehicle.enter_time = 0;

    if (wq->front == -1) return empty_vehicle;

 

    Vehicle v = wq->data[wq->front];

    if (wq->front == wq->rear) {

        wq->front = wq->rear = -1;

    } else {

        wq->front = (wq->front + 1) % MAX_WAITING;

    }

    return v;

}

 

bool isQueueEmpty(WaitingQueue *wq) {

    return wq->front == -1;

}

 

bool isParkingFull(ParkingStack *ps) {

    return ps->top == MAX_PARKING - 1;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值