设停车场是一个可以停放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;
}
停车场管理系统的设计与实现
1208

被折叠的 条评论
为什么被折叠?



