1.问题描述
设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若停车场已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在其之后开入的车辆必须先退出停车场让路,待该辆车开出大门外,其他车辆再按原次序进入停车场,每辆停放在停车场的车在其离开停车场时必须按其停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。
2.设计要求
以栈模拟停车场,以队列模拟停车场外的便道,按照从终端读入的输入数据的方式进行模拟管理。输入1,表示车辆到达;输入2,表示车辆离开;输入3,表示显示出停车场内及便道上的停车情况;输入4,表示退出系统。车辆到达操作,需输入汽车牌照号码及到达时间;车辆离开操作,需输入汽车在停车场的位置及离开时刻,且应输出汽车在停车场内停留的时间和应缴纳的费用(在便道上停留的时间不收费)。
3.代码实现
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define OK 1
#define OVERFLOW -2
#define SIZE 2//停车场位置数,这里设置小点方便数据输入
typedef int Status;
//停在停车场中的车(通过顺序栈实现)
typedef struct Car1
{
int number;//车号
int arr_time;//抵达时间
}CarNode;
//停车位结点(栈)
typedef struct
{
CarNode *base;//堆栈底
CarNode *top;//堆栈顶
int stacksize;
}Park;
//停在临时通道内的车(通过单链表实现)
typedef struct Car2
{
int number;//车号
int arr_time;//到达时间
struct Car2 * next;
}*CarPtr,CarNode2;
//临时通道
typedef struct
{
CarPtr front;//队列的队头
CarPtr rear;//队列的队尾
int length;
}Shortcut;
//初始化停车场
Status InitStack(Park &P)
{
P.base=(CarNode *)malloc(SIZE*sizeof(Car1));
if(!P.base)
exit(OVERFLOW);
P.top=P.base;
P.stacksize=0;
return OK;
}
//车进入停车场
Status Push(Park &P,CarNode e)
{
*P.top++=e;
++P.stacksize;
return OK;
}
//车离开停车场
Status Pop(Park &P,CarNode &e)
{
if(P.top==P.base)
printf("停车场为空");
else
{
e=*--P.top;
--P.stacksize;
}
return OK;
}
//初始化临时通道
Status InitQueue(Shortcut &S)
{
S.front=S.rear=(CarPtr)malloc(sizeof(Car2));
if(!S.front||!S.rear)
exit(OVERFLOW);
S.front->next=NULL;
S.length=0;
return OK;
}
//车子进入临时通道
Status EnQueue(Shortcut &S,int number,int arr_time)
{
CarPtr p;
p=(CarPtr)malloc(sizeof(Car2));
if(!p)
exit(OVERFLOW);
p->number=number;
p->arr_time=arr_time;
p->next=NULL;
S.rear->next=p;
S.rear=p;
++S.length;
return OK;
}
//车子离开临时通道,进入停车场
Status DeQueue(Shortcut &S,CarPtr &w)
{
if(S.length==0)
printf("通道为空");
else
{
w=S.front->next;
S.front->next=w->next;
--S.length;
}
return OK;
}
//对进栈车辆的处理
Status Arrival(Park &P,Shortcut &S)
{
int number,arr_time;
printf("请输入车牌号:");
scanf("%d",&number);
printf("请输入进停车场的时间,以24进制,例如下午4:35写成1635:");
scanf("%d",&arr_time);
if(P.stacksize<SIZE)
{
CarNode c;
c.number=number;
c.arr_time=arr_time;
Push(P,c);
printf("该车停在第%d号位置\n",P.stacksize);
}
else
{
EnQueue(S,number,arr_time);
printf("停车场已满,暂时停在便道的第%d个位置。\n",S.length);
}
return OK;
}
//停车场的车离栈,同时计算车费;临时通道内的车进入停车场
Status Leave(Park &P,Park &P1,Shortcut &S)
{
int number,le_time,flag=1,money,arr_time;
printf("请输入离开车辆车牌号:");
scanf("%d",&number);
printf("请输入离开时间,以24小时制表示:");
scanf("%d",&le_time);
CarNode e,m;
CarPtr w;
while(P.stacksize)
{
Pop(P,e);//车辆离开
if(e.number==number)
{
flag=0;
money=(le_time-e.arr_time)*2;//费用是总时间乘以2
arr_time=e.arr_time;
break;
}
//临时做个栈,然后将让道的车辆信息暂时存储在这个临时栈内
Push(P1,e);
}
//将临时栈内的信息插入停车场
while(P1.stacksize)
{
Pop(P1,e);
Push(P,e);
}
if(flag==0)
{
if(S.length!=0)
{
DeQueue(S,w);
m.arr_time=le_time;//新进入的车的时间等于离开车的时间
m.number=w->number;
Push(P,m);
free(w);
printf("车牌号为%d的车已经由便道进入停车场\n",m.number);
}
printf("停车费为%d,占用车位数为%d\n",money,P.stacksize);
}
else
{
printf("停车场不存在车辆为%d的车",number);
}
return OK;
}
//展示停车场车辆的车牌号
Status DisplayStack(Park p)
{
printf("停车场停车信息如下(先进的车辆在最右端):\n");
if(p.base==NULL)
return OVERFLOW;
if(p.top==p.base)
printf("停车场中没有车");
CarNode *q;
q=p.top;
while(q>p.base)
{
q--;
printf("%d ",q->number);
}
printf("\n");
return OK;
}
//展示临时车道的车牌号
Status DisplayQueue(Shortcut s)
{
printf("临时通道停车信息如下(先进的车辆在最右端):\n");
if(s.front==s.rear)
printf("临时通道内没车");
CarPtr p;
p=s.front->next;
while(p)
{
printf("%d ",p->number);
p=p->next;
}
printf("\n");
return OK;
}
int main()
{
int m=1;
char flag; //选项
Park P,Q;
Shortcut S;
InitStack(P);
InitStack(Q);
InitQueue(S);
while(m)
{
printf("1 汽车进车场\n");
printf("2 查看停车场\n");
printf("3 汽车出车场\n");
printf("4 退出程序\n");
printf("请选择(1,2,3,4): ");
scanf("%c",&flag);
switch(flag)
{
case '1':
Arrival(P,S);break; //车进入停车场
case '2':
DisplayStack(P);
DisplayQueue(S);
break;
case '3':
Leave(P,Q,S);break; //车离开停车场
case '4':
m=0;
break;
default:
printf("Input error!\n");
break;
}
while (flag != '\n')
scanf("%c",&flag);
}
return 0;
}