一、题目描述
(1)问题描述
设停车场是一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。
(2)基本要求
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。栈以顺序结构实现,队列以链表实现。
(3)测试数据
设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’表示输入结束
二、 程序设计
采用了四个结构体,分别是:车辆信息结构体、用来构建存储车辆信息的顺序栈结构体、用来实现队列的链表结构体、用来构建存储车辆信息的单链表结构的队列结构体。然后定义了八个功能的函数来实现相关操作,具体如下:
建栈:采用顺序结构建立栈,存储停车场内车辆信息
进栈:每到来一辆车,若停入停车场内,则进行压栈处理
出栈:若停车场内的车离开,则进行出栈处理
建队:采用单链表结构建立一个队列,用来存储便道上的车辆信息。
进队:若车辆到来停在便道上,则进行进队处理。
出队:若车辆从便道上离开,则进行出队处理。
出队后队列重排:若车辆从便道上离开停车场,需对便道上的车辆进行重新排队。
输入数据进行操作:输入车辆信息后,执行对应操作。
三、代码(附一些注释):
#include<stdio.h>
#include<malloc.h>
#include <stdlib.h>
#define STACK_SIZE 100
typedef struct//车辆信息结构体
{
char AD;
int num;
int time;
}car;
typedef struct//用来构建存储车辆信息的顺序栈
{
car *top;
car *base;
int N;
int stacksize;
}SqStack;
typedef struct QNode//用来实现队列的链表结构
{
car data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct//用来构建存储车辆信息的单链表结构的队列
{
QueuePtr front;
QueuePtr rear;
int N;
}LinkQueue;
void InitStack(SqStack &Sq);//构建一个顺序栈
void Push(SqStack &Sq,car &C);//压栈
int Pop(SqStack &Sq,car &C);//判断车辆是否在栈中(停车场内),是则出栈
void InitQueue(LinkQueue &Q);//构建一个单链表队列
void EnQueue(LinkQueue &Q,car &C); //入队
int DeQueue(LinkQueue &Q,car &C2);//出队(然后用来入栈)
int DeQueue_out(LinkQueue &Q,car &C);//出队,重新调整队列
// 对输入车辆信息执行相关操作
void operation(car &C,SqStack &Sq,LinkQueue &Q);
int n;//停车场位置个数
int price;//价格
int main()
{
printf(" *******欢迎使用停车场管理模拟程序********\n");
printf("请输入停车场的最大停车位数:");
scanf("%d",&n);
printf("请输入停车场的收费标准(输入数字,单位:yuan/minute):");
scanf("%d",&price);
car C;
printf("***请依次输入汽车到达(A)或离去(D)信息(E结束输入)、汽车牌照号码、到达或离去时刻***\n");
scanf("%c %d %d",&C.AD,&C.num,&C.time);
SqStack Sq;//构建栈
LinkQueue Q;//构建一个队列
InitStack(Sq);
InitQueue(Q);
while(C.AD!='E')
{
operation(C,Sq,Q);
printf("***请依次输入汽车到达(A)或离去(D)信息(E结束输入)、汽车牌照号码、到达或离去时刻***\n");
scanf("%c %d %d",&C.AD,&C.num,&C.time);
}
return 0;
}//程序结束
void InitStack(SqStack &Sq)
{
Sq.base=(car *)malloc(STACK_SIZE * sizeof(car));//分配空间
if(!Sq.base) exit(0);
Sq.top=Sq.base;
Sq.stacksize=STACK_SIZE;
Sq.N=0;//停车位置
}
void Push(SqStack &Sq,car &C)
{
if(Sq.N>=Sq.stacksize)
{
Sq.base=(car *) realloc(Sq.base,(Sq.stacksize+1)*sizeof(car));//追加分配空间
if(!Sq.base) exit(0);
Sq.top=Sq.base+Sq.stacksize;
Sq.stacksize+=1;
}
*Sq.top++=C;
Sq.N++;
}
int Pop(SqStack &Sq,car &C)
{
car C1;
SqStack Sq1;
InitStack(Sq1);
while(Sq.top->num!=C.num&&Sq.top!=Sq.base)//压到另一个栈中
{
Push(Sq1,*Sq.top);
*Sq.top--;
Sq.N--;
Sq.stacksize--;
}
int time=Sq.top->time;
Sq.N--;
Sq.stacksize--;
int a=1;
if(Sq.top==Sq.base&&Sq.top->num!=C.num) a=0;//判断该车是否在栈中
while(Sq1.top!=Sq1.base)//将出栈的元素重新压回来
{
Push(Sq,*--Sq1.top);
Sq1.stacksize--;
Sq1.N--;
}
if(a==0) // 该车不在栈中,返回0
{
Sq.N++;
return 0;
}
else return time;//该车在栈中,返回时间
}
void InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front) exit(0);
Q.front->next=NULL;
Q.N=0;
}
void EnQueue(LinkQueue &Q,car &C)
{
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p) exit(0);
p->data=C;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
Q.N++;
}
int DeQueue(LinkQueue &Q,car &C2)
{
if(Q.front==Q.rear) return 0;
QueuePtr p;
p=Q.front->next;
C2=p->data;
Q.front->next=p->next;
Q.N--;
if(Q.rear==p) Q.rear=Q.front;
free(p);
return 1;
}
int DeQueue_out(LinkQueue &Q,car &C)
{
car C3;
LinkQueue Q1;
InitQueue(Q1);
if(Q.front==Q.rear) return 0;
while(Q.front->next!=Q.rear)//将除了该车,其他车重新排到另一个队列中
{
car C4=Q.front->data;
if(C4.num!=C.num)
{
DeQueue(Q,C3);
EnQueue(Q1,C3);
}
}
while(Q1.front->next!=Q1.rear)//将原队列重排好
{
DeQueue(Q1,C3);
EnQueue(Q,C3);
}
}
void operation(car &C,SqStack &Sq,LinkQueue &Q)
{
if(C.AD=='A')
{
if(Sq.N>=n)
{
EnQueue(Q,C);
printf("该车停留在便道上的位置为:No.%d\n\n",Q.N);
}
else
{
Push(Sq,C);
printf("该车停留在停车场内的位置为:No.%d\n\n",Sq.N);
}
}
if(C.AD=='D')
{
int t;
t=Pop(Sq,C);
if(t)
{
printf("该车在停车场内停留时间为:%d 分钟,需缴纳费用为:%d yuan\n\n",C.time-t,(C.time-t)*price);
}
else
{
printf("该车停在便道,不需缴纳费用\n\n");
}
if(Q.front!=Q.rear)
{
if(t==0) DeQueue_out(Q,C);
else//出队与入栈
{
car C2;
DeQueue(Q,C2);
C2.time=C.time;
Push(Sq,C2);
}
}
}
}
四、运行结果