停车场

参照教学章节的教学视频,完成下面的实验 设停车场是一个可停放n辆车的狭长通道,且只有一个大门可供汽车进出。在停车场内,汽车按到达的先后次序,由北向南依次排列(假设大门在最南端)。若车场内已停满n辆车,则后来的汽车需在门外的便道上等候,当有车开走时,便道上的第一辆车即可开入。当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门后,其他车辆再按原次序返回车场。每辆车离开停车场时,应按其停留时间的长短交费(在便道上停留的时间不收费),示意图如下。

COMMON.C
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h> //获取系统时间的相关库

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

SEQSTACK.H
#include"common.h"
#define Stack_Size 50 //设顺序栈中最大元素个数为50,即停车场最多能容纳车

typedef struct //自定义结构类型,用来存放车辆信息,队列和栈都有使用,所以放在common.h中
{
int CarNo; //车牌号
time_t Itime; //进场时间
time_t Otime; //出场时间
}StackElementType;

//栈结构定义
typedef struct
{
StackElementType elem[Stack_Size]; //栈中存放数据元素的一维数组
int top; //栈顶指示器,-1表示空栈
}SeqStack;

//栈的初始化
void InitStack(SeqStack S);
//进栈
int Push(SeqStack
S,StackElementType x);
//出栈
int Pop(SeqStack*S,StackElementType x);
//读取栈顶元素
int GetTop(SeqStack
S,StackElementType *x);
//是否满栈
int FullStack(SeqStack *S);
//是否空栈
int EmptyStack(SeqStack *S);

SEQQUEUE.H
#include"common.h"
#define MAXSIZE 50 //队列的最大长度

typedef struct //自定义结构类型,用来存放车辆信息,队列和栈都有使用,所以放在common.h中
{
int CarNo; //车牌号
time_t Itime; //进场时间
time_t Otime; //出场时间
}QueueElementType;

//队列的定义,用于待停临时候停区
typedef struct
{
QueueElementType element[MAXSIZE]; //队列的元素空间
int front; //头指示器
int rear; //尾指示器
}SeqQueue;

//初始化操作
void InitQueue(SeqQueue Q)
{
Q->front=Q->rear=0; //将
Q初始化为一个空的循环队列
}

//入队操作,将元素x入队
int EnterQueue(SeqQueue*Q,QueueElementType x)
{
if((Q->rear+1)%MAXSIZE==Q->front) //队列已经满了
return(FALSE);
Q->element[Q->rear]=x;
Q->rear=(Q->rear+1)%MAXSIZE; //重新设置队尾指示器
return(TRUE);
}

//出队操作,删除队列的队头元素,用x返回其值
int DeleteQueue(SeqQueue *Q,QueueElementType *x)
{
if(Q->front==Q->rear) //如果队列为空
return(FALSE);
*x=Q->element[Q->front];
Q->front=(Q->front+1)%MAXSIZE; //重新设置队头指针
return(TRUE);
}

//或取队列的队头元素,用x返回其值
int GetHead(SeqQueue *Q,QueueElementType *x)
{
if(Q->front==Q->rear) //队列为空
return(FALSE);
*x=Q->element[Q->front]; //返回值到x
return(TRUE);
}

//判断队列是否为空
int IsEmpty(SeqQueue *Q)
{
if(Q->front==Q->rear) //队列为空
return(TRUE);
else
return(FALSE);
}

SEQSTACK.C
#include"seqstack.h"

//栈的初始化
void InitStack(SeqStack *S)
{
S->top=-1; //栈顶指针指向-1,表示空栈
}

//进栈,车辆进入停车场
int Push(SeqStack *S,StackElementType x)
{
//如果栈满,返回FALSE
if(S->top==Stack_Size-1)
return FALSE;
S->top++; //栈顶指针上移
S->elem[S->top]=x;
return TRUE;
}

//出栈:车辆离场
int Pop(SeqStack*S,StackElementType *x)
{
//如果栈空,返回FALSE
if(S->top==-1)
return FALSE;
*x=S->elem[S->top]; //栈顶元素赋值给x
S->top–; //栈顶指针下移
return TRUE;
}

//读取栈顶元素
int GetTop(SeqStack*S,StackElementType *x)
{
//如果栈空,返回FALSE
if(S->top==-1)
return FALSE;
*x=S->elem[S->top]; //栈满
return TRUE;
}

//是否满栈
int FullStack(SeqStack *S)
{
if(S->top+1==Stack_Size) //栈满
return TRUE;
else
return FALSE;
}

//是否空栈
int EmptyStack(SeqStack *S)
{
if(S->top==-1) //栈为空
return TRUE;
else
return FALSE;
}
MAIN.C
#include"seqstack.h" //栈的算法
#include"seqqueue.h" //队列的算法

int main()
{
int op=1; //操作控制命令
float money=0; //计算停车费,每秒0.5元
time_t t; //系统定义的时间类型,单位是秒

int cNo;        //车牌号
StackElementType car;    //栈中存放车辆信息数据
QueueElementType carQ;   //队列中存放车辆信息,候车时

SeqStack Park,TemPark;   //分别表示停车场和临时挪车停车场
InitStack(&Park);        //栈初始化
InitStack(&TemPark);

SeqQueue WaitPark;       //待停区队列
InitQueue(&WaitPark);    //队列初始化

while(op!=0)             //循环操作指令,当输入0时退出
{
	printf("*欢迎使用停车管理系统,请输入你的操作:\
	\n*1.车辆进场\n*2.车辆出场\n*0.退出系统\n*请输入对应操作的数字:\n"); 
	scanf("%d",&op);
	if(op==1)        //进场操作 
	{
		//车辆进场时获取车辆信息
		printf("请输入车牌号:");
		scanf("%d",&cNo);
		if(FullStack(&Park))      //如果停车场已满,则进入待停区
		{
			carQ.CarNo=cNo;
			EnterQueue(&WaitPark,carQ);   //入队,进入待停区 
			printf("车辆:%d进入待停区.\n",cNo); 
		}	
		else       //停车场未满
		{
			car.CarNo=cNo;
			time(&t);            //获取当前时间,单位是秒
			car.Itime=t;         //将进场时间存入
			//进场即进栈
			if(Push(&Park,car))  //如果进场成功
			printf("车辆,%d进场:\n",cNo); 
		}
		 		 
	}
	if(op==2)      //2车辆出场操作
	{
		//获取要出场车辆牌号
		printf("请输入车牌号:");
		scanf("%d",&cNo);
		int find=0;               //标记变量,0表示未找到对应车牌车辆,1表示找到对应车辆 
		while(!EmptyStack(&Park)&&!find)     //如果有停车辆且没找到车,就执行操作 
		{
			//从停车场栈顶开始查找车牌,不是对应车辆就把车辆出栈,就入挪车栈
			if(Pop(&Park,&car))   //停车场最外面的车辆出场 
			{
				if(car.CarNo!=cNo)   //牌号不匹配,出栈的车辆进入挪车栈,则继续查找此车牌
				{
					if(Push(&TemPark,car))   //如果成功进入挪车区
					   printf("车辆:%d进入挪车区.\n",car.CarNo);
					else
					   printf("车辆:%d进入挪车区失败.\n",car.CarNo);
				}
				else      //如果查询到车牌,则车辆出场,待停区如果有车辆则进场一辆
				{
					find=1;    //找到车辆,不再找车
					//车辆出场
					time(&t);      //获取系统时间(单位是秒)
					car.Otime=t;   //获取车辆出场时间
					money=(car.Otime-car.Itime)*0.5;    //计算停车费,每秒0.5元
					printf("车辆:%d出场,停车费:%.1f元.\n",cNo,money);
					//挪车区车辆再次进入停车区
					while(Pop(&TemPark,&car))     //当挪车区不为空时,一直出栈
					{
						if(Push(&Park,car))       //车辆重新进入停车场
						   printf("车辆:%d重新进入停车场.\n",car.CarNo); 
					}
					//此时有空一位,待停区有车则进场
					if(!IsEmpty(&WaitPark))  //如果待停区有车,则出队一两车,然后进入停车场
					{
						DeleteQueue(&WaitPark,&carQ);   //出队
						car.CarNo=carQ.CarNo;
						time(&t);            //获取当前时间,单位是秒 
						car.Itime=t;         //将进场时间存入 
						if(Push(&Park,car))  //如果进场成功 
						printf("车辆:%d自待停区进场.\n",cNo); 
					} 
				} 
			} 
		}
		
		if(find==0)       //如果始终没有找到要出场的车牌号,则所有车辆在挪车区,需要回停车位 
		{
			printf("没有找到牌号:%d车辆.\n",cNo);
			while(Pop(&TemPark,&car))      //当挪车区不为空时,一直出栈 
			{
				if(Push(&Park,car))        //车辆重新进入停车场 
				printf("车辆:%d重新进入停车场.\n",car.CarNo); 
			} 
		}
	}
		 
}
return 0;

}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个可以停放n辆汽车的狭长停车场,它只有一个大门可以供车辆进出。车辆按到达停车场时间的早晚依次从停车场最里向大门口处停放(最先到达的第一辆车放在停车场的最里面)。如果停车场已放满n辆车,则后来的车只能在停车场大门外的便道上等待,一旦停车场内有车开走,则排在便道上的第一辆车就进入停车场停车场内如有某辆车要开走,在它之后进入停车场的车都必须先退出停车场为它让路,待其开出停车场后,这些车辆再依原来的次序进场。每辆车在离开停车场时,都应根据它在停车场内停留的时间长短交费。如果停留在便道上的车未进停车场就要离去,允许其离去,不收停车费,并且仍然保持在便道上等待的车辆次序。编制一程序模拟该停车场的管理。(2) 实现要求:要求程序输出每辆车到达后的停车位置(停车场或便道上),以及某辆车离开停车场时应交纳的费用和它在停车场内停留的时间。(2) 实现提示:汽车的模拟输入信息格式可以是:(到达/离去,汽车牌照号码,到达/离去的时刻)。例如,(’A’,1,5)表示1号牌照车在5时刻到达,而(’D’,5,20)表示5号牌照车在20时刻离去。整个程序可以在输入信息为(’E’,0,0)时结束。本题可用顺序存储结构和链式存储结构来实现。本人的一个数据结构课程计(用C++源码实现,供大家学习参考之用,有不妥之处望指正)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值