停车场管理
1.项目简介
设停车场是一个可以停放n辆汽车的南北方向的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆车,那么后来的车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。要求程序输出每辆车到达后的停车位置(停车场或便道上),以及某辆车离开停车场时应缴纳的费用和它在停车场内停留的时间。
2.设计思路
停车场的管理流程如下:
①当车辆要进入停车场时,检查停车场是否已满,如果未满则车辆进入停车场;如果停车场已满,则车辆进入便道等候。
②当车辆要求出栈时,先让在它之后进入停车场的车辆退出停车场为它让路,再让该车退出停车场,让路的所有车辆再按其原来进入停车场的次序进入停车场。之后,再检查在便道上是否有车等候,有车则让最先等待的那辆车进入停车场。
3.数据结构
由于停车场只有一个大门,当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,先进停车场的后退出,后进车场的先退出,符合栈的“后进先出,先进后出”的操作特点,因此,可以用一个栈来模拟停车场。而当停车场满后,继续来到的其它车辆只能停在便道上,根据便道停车的特点,先排队的车辆先离开便道进入停车场,符合队列的“先进先出,后进后出”的操作特点,因此,可以用一个队列来模拟便道。排在停车场中间的车辆可以提出离开停车场,并且停车场内在要离开的车辆之后到达的车辆都必须先离开停车场为它让路,然后这些车辆依原来到达停车场的次序进入停车场,因此在前面已设的一个栈和一个队列的基础上,还需要有一个地方保存为了让路离开停车场的车辆,由于先退出停车场的后进入停车场,所以很显然保存让路车辆的场地也应该用一个栈来模拟。因此,本题求解过程中需用到两个栈和一个队列。栈以顺序结构实现,队列以顺序结构或链表结构实现。
4.程序清单
程序提示:以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码以及到达或离去的时刻。对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。
参考代码:
//模拟停车场的堆栈的性质; typedef struct zanlind{ int number; //汽车车号 int ar_time; //汽车到达时间 }zanInode; typedef struct{ zanInode *base; //停车场的堆栈底 zanInode *top; //停车场的堆栈顶 int stacksize_curren; }stackhead; //模拟便道的队列的性质; typedef struct duilie{ int number; //汽车车号 int ar_time; //汽车到达时间 struct duilie *next; }*queueptr; typedef struct{ queueptr front; //便道的队列的对头 queueptr rear; //便道的队列的队尾 int length; }linkqueue;
程序主要功能:
车辆到达;车辆离开;计算停车费用;查询车辆信息;输出车辆信息。
函数之间的调用关系:
1.调用函数void InitStack (SeqStackCar *); 初始化栈模拟停车场。
2.调用函数int InitQueue (LinkQueueCar *) ; 初始化队列模拟便道。
3.调用函数int Arrival (SeqStackCar *, LinkQueueCar *); 车辆到达。
4.调用函数void Leave (SeqStackCar *, SeqStackCar *, LinkQueueCar *); 车辆离开。
5.调用函数void List (SeqStackCar, LinkQueueCar); 显示存车信息。
6.调用函数void PRINT (CarNode*p) ;打印信息。
详细设计
1.车辆到达
if (Enter->top<MAX) /*车场 未满,车进车场*/ { Enter->top++; printf ("\n\t\t\t该车辆在停车场的位置是: %\n",Enter->top); printf(" \n\t\t\t请输入该车辆到达的时间: ") ; scanf ("%d", & (p->reachtime)); Enter->stack[Enter->top]=p; return(1) ; } else
2.车辆离开
if (Enter->top>0) /*有车*/ { while(1) /*输入离开车辆的信息*/ { printf(" \t\t\t停车场里停放的车辆总数: %d", Enter->top) ; printf(" \n\n\t\t\t请输入要离开车辆的位置: ") ; scanf ("%d" , &room) ; if (room>=1&&room<=Enter->top) break;} while (Enter->top>room) /*车辆离开*/
3.主函数
while(1) { scanf("%d" , &ch) ; printf("\n") ; if (ch>= 1&&ch<=4) break; else printf("\n\t\t\t错误!请再次做出选择! \n\n\t\t\t");} switch (ch) { case 1:Arrival (&Enter, &Wait) ; break; /*车辆到达*/case 2: Leave (&Enter, &Temp, &Wait) ; break; /*车辆离开 */ case 3:List (Enter, Wait); break; /*列表打印信息*/ case 4:exit(0) ; /*退出主程序*/ default: break; }
带注释的源程序:
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX 2 /*车库容量*/ #define price 3 /*每车每时刻费用*/ typedef struct node { int num; int reachtime; int leavetime; }CarNode; /*车辆信息结点*/ typedef struct NODE { CarNode *stack [MAX+1]; int top; } SeqStackCar; /* 模拟车站*/ typedef struct car {CarNode *data; struct car *next ; } QueueNode; typedef struct Node { QueueNode *head; QueueNode *rear ; }LinkQueueCar; /*模拟通道*/ /*函数声明部分*/ void InitStack (SeqStackCar *); /*初始化栈*/ int InitQueue (LinkQueueCar *) ; /*初始化便道*/ int Arrival (SeqStackCar *, LinkQueueCar *); /*车辆到达*/ void Leave (SeqStackCar *, SeqStackCar *, LinkQueueCar *); /*车辆离开*/ void List (SeqStackCar, LinkQueueCar); /*显示存车信息*/ void PRINT (CarNode*p) ; int main() { SeqStackCar Enter, Temp; LinkQueueCar Wait; int ch; InitStack (&Enter); /*初始化车站*/ InitStack (&Temp); /*初始化让路的临时栈*/ InitQueue (&Wait); /*初始化通道*/ while(1) { printf(" \n\n\t\t\t1.车辆到达请选择1"); printf("\n\n\t\t\t2.车辆离开请选择2"); printf(" \n\n\t\t\t3.车辆信息请选择3"); printf("\n\n\t\t\t4.退出程序请选择4"); printf("\n\n\t\t\t现在请选择以上信息: "); while(1) { scanf("%d" , &ch) ; printf("\n") ; if (ch>= 1&&ch<=4) break; else printf("\n\t\t\t错误!请再次做出选择! \n\n\t\t\t");} switch (ch) { case 1:Arrival (&Enter, &Wait) ; break; /*车辆到达*/case 2: Leave (&Enter, &Temp, &Wait) ; break; /*车辆离开 */ case 3:List (Enter, Wait); break; /*列表打印信息*/ case 4:exit(0) ; /*退出主程序*/ default: break; } } } void InitStack (SeqStackCar *s) /*初始化栈*/ { int i; s->top=0; for(i=0;i<=MAX;i++) s->stack[s->top]=NULL; } int InitQueue (LinkQueueCar *Q) /*初始化便道*/ {Q->head= (QueueNode *) malloc (sizeof (QueueNode)) ; if (Q->head!=NULL) {Q->head->next=NULL; Q->rear=Q->head; return(1) ; } else return(-1) ; } void PRINT (CarNode *p) /*打 印出站车的信息*/ {int A1, A2; printf ("\n\t\t\t请输入离开时间: ") ; scanf(" %d" , &(p->leavetime)) ; printf("\n\t\t\t离开车辆的车牌号: %d",p->num) ; printf ("\n\n\t\t\t离开车辆到达时间: %d", p->reachtime) ; printf("\n\n\t\t\t离开车辆离开时间: %d" , p->leavetime) ; A1=p->reachtime; A2=p->leavetime; printf(" \n\n\t\t\t停车场管理费用: %d", (A2- -A1) *price) ;free(p); } int Arrival (SeqStackCar *Enter, LinkQueueCar *W) /* 车辆到达*/ { CarNode *p; QueueNode *t ; p= (CarNode *) malloc (sizeof (CarNode)) ; printf("\t\t\t请输入到达车辆车牌号: "); scanf ("%d", & (p->num)); if (Enter->top<MAX) /*车场 未满,车进车场*/ { Enter->top++; printf ("\n\t\t\t该车辆在停车场的位置是: %\n",Enter->top); printf(" \n\t\t\t请输入该车辆到达的时间: ") ; scanf ("%d", & (p->reachtime)); Enter->stack[Enter->top]=p; return(1) ; } else /*车场已满,车进便道*/ { printf(" \n\t\t\t停车场已满 该车辆需在便道上等待! ");getchar() ; t= (QueueNode *) malloc (sizeof (QueueNode)) ; t->data-p; t->next-NULL; W->rear->next=t;W->rear=t; return(1) ; } } void Leave (SeqStackCar *Enter, SeqStackCar *Temp, LinkQueueCar*W) /*车 辆离开*/ { int room; CarNode *p, *t; QueueNode *q; /*判断车场内是否有车*/ if (Enter->top>0) /*有车*/ { while(1) /*输入离开车辆的信息*/ { printf(" \t\t\t停车场里停放的车辆总数: %d", Enter->top) ; printf(" \n\n\t\t\t请输入要离开车辆的位置: ") ; scanf ("%d" , &room) ; if (room>=1&&room<=Enter->top) break;} while (Enter->top>room) /*车辆离开*/ {Temp->top++; Temp->stack [Temp->top] =Enter->stack [Enter->top]; Enter->stack [Enter->top]=NULL; Enter->top-- ; } p=Enter->stack [Enter->top]; Enter->stack [Enter->top]=NULL; Enter->top-- ; while (Temp->top>=1) {Enter->top++; Enter->stack[Enter->top]=Temp->stack[Temp->top]; Temp->stack [Temp->top]=NULL; Temp->top-- ; } PRINT(p) ; /*判断通道上是否有车及车站是否已满*/ if((W->head!=W->rear)&Enter->top<MAX) /*便道的车辆进入车场*/ { q=W->head->next; t=q->data; Enter-> top++; printf("\n\n\t\t\t便道的%d号车进入车场第%d位置", t->num, Enter->top) ; printf(" \n\n\t\t\t靖輸入現在的吋同:"); scanf ("%d", & (t->reachtime)) ; W->head->next=q->next; if(q==W->rear) W->rear-W->head; Enter->stack [Enter->top]=t; free (q) ; } else printf(" \n\n\t\t\t便道里没有车. \n"); } else printf(" \n\n\t\t\t车场里没有车."); /*没车*/ } void List1 (SeqStackCar *S) /*列表 显示车场信息*/ { int i; if(S->top>0) /*判断车站内是否有车*/ { printf(" \n\t\t\t车场:") ; printf("\n\n\t\t\t位置到达时间车牌号\n"); for(i=1;i<=S->top;i++) {printf("%26d", i); printf("%6d", S->stack[i]->reachtime) ; printf("%10d", S->stack[i]->num) ; printf("(n"); } } else printf(" \n\t\t\t车场里没有车"); } void List2 (LinkQueueCar *W) /*列表显示便道信息*/ {QueueNode *p; p=W->head->next; if (W->head!=W->rear) /*判断通道.上是否有车*/ { printf("\n\t\t\t等待车辆的号码为: "); while (p!=NULL) { printf("%- 10d", p->data->num) ; p=p->next; } printf("\n") ; } else printf("\n\t\t\t便道里没有车."); } void List (SeqStackCar S, LinkQueueCar W) { int flag, tag; flag=1; while(flag) { printf("\n\t\t\t请选择 1|2|3:"); printf("\n\n\t\t\t1. 车场\n\n\t\t\t2. 便道\n\n\t\t\t3. 返回\n\n\t\t\t"); while(1) {scanf("%d" , &tag) ; if (tag>=1||tag<=3) break; else printf("\n\t\t\t请选择1|2|3:") ; } switch (tag) { case 1:List1(&S) ;break; /*列表显示车场信息*/ case 2:List2 (&W) ; break; /*列表显示便道信息*/ case 3:flag=0; break; default: break; } } }