停车场问题——栈和队列

【问题描述】
设有一个可以停放n 辆汽车的狭长停车场,它只有一个大门可以供车辆进出。车辆按到达停车场时间的早晚依次从停车场最里面向大门口处停放
(最先到达的第一辆车放在停车场的最里面)。如果停车场已放满n辆车,则后来的车辆只能在停车场大门外的便道上等待,一旦停车场内有车开走,
则排在便道上的第一辆车就进入停车场。停车场内如有某辆车要开走,在它之后进入停车场的车辆都必须先退出停车场为它让路,待其开出停车场后,
这些车辆再依原来的次序进场。每辆车在离开停车场时,都应该根据它在停车场内停留的时间长短交费。如果停留在便道上的车未进停车场就要离去,
允许其离去,不收停车费,并且仍然保持在便道上等待的车辆的次序。编制一程序模拟该停车场的管理。

【基本要求】
以栈模拟停车场,以队列模拟车场外的便道,按照输入的数据序列进行模拟管理,每一组输入数据包括三个数据项:汽车到达或离去的信息、
汽车牌照号码以及到达或离去的时刻。要求程序输出每辆车到达后的停车位置(停车场或便道上),以及某辆车离开停车场时应交纳的费用和它在停车场内停留的时间。

【提示及分析】
需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也用顺序存储结构实现。输入数据按到达或离去的时刻有序。
栈中每个元素表示一辆汽车,包含两个数据:汽车的拍照号码和进入停车场的时刻。

【测试数据】
设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’表示输入结束。

实验环境: devc++
代码实现:

#include<iostream>
using namespace std;
#define MAX_SIZE 2
// 构造顺序栈和链式队列 
//1.结构定义
//1.1 数据域的定义 
typedef struct Parking_Car{ //栈和队列中存放的数据域 
	char status;
	string number;
	int start_time;
	int end_time;
	
}Parking_Car; 

//1.2 停车场的定义,本质上是个顺序栈的定义 
typedef struct Parking_Lot{
	struct Parking_Car *car;
	int top; //指向的是栈中的顶部元素 
}Parking_Lot; 

//1.3 便道的定义, 本质上是顺序队列的定义 
typedef struct Street{
	int front; //头部指针 
	int rear; //尾部指针 
	Parking_Car *car;  //数据和两个指针 
}Street; 

//2.初始化
//2.1 初始化数据 
Parking_Car* init_PC(char s,string num,int time){
	Parking_Car *pc = new Parking_Car;
	pc->status = s;
	pc->number = num;
	pc->start_time = time;
	pc->end_time = -1; //为负数说明还没有出停车场,所以初始给了负数 
	return pc;
}

//2.2 初始化停车场 
Parking_Lot* init_PL(){
	Parking_Lot* pl = new Parking_Lot;
	pl->car = new Parking_Car[MAX_SIZE];
	pl->top = -1;
	
	return pl;
} 

//2.3.初始化队列 
Street *init_Street(){
	Street *s = new Street;
	s->car = new Parking_Car[10];
	s->front = s->rear = 0;
	return s;
} 

//3.进行数据的操作
//3.1 车进入停车场,实际上是车入栈 
int in_parking(Parking_Lot *PL,Parking_Car *car){
	if(PL->top >= MAX_SIZE) return -1; //此时表示停车场已满,不能再进入
	//2.将数据押入到栈中
	PL->car[++PL->top] = *car;
	return 0; 
} 

//3.2 车从停车场中出去,实际上是出栈,
//此时的出是指定车进行出去,所以要把指定的车之前的所有车全部出去之后才能出去

Parking_Car out_parking(Parking_Lot *PL,string num,int time){ //此时传入的是要出去的车的序号,和出去的时间 
	//1.首先判断栈是否为空 
		Parking_Lot* tmp = init_PL();//创建一个临时的空的停车站用于中转 
		Parking_Car out_car;
		//2.要找到指定出去的车的车牌号
		while(1){
			if(PL->top<0)
				break;
			//2.1 要把指定的车之前的所有车全部出去,将前面的车放入到暂时的中转站 
			if(PL->car[PL->top].number != num){
				in_parking(tmp,&PL->car[PL->top]);  //将前面的车放入到暂时的中转站 
				PL->top--; 
			}
			else{
				//2.2 进入到这个里面说明找到了指定的要离开的车
				PL->car[PL->top].end_time = time; //此时就可以对离开时间进行赋值了 
				out_car = PL->car[PL->top]; //将离开的车量信息进行返回,用于记录 
				PL->top--;
				break;
				 
			}		

		} 
		//3.还要将暂时中转站里的车重新进入到原栈中
		while(tmp->top >= 0){
			in_parking(PL,&tmp->car[tmp->top--]);
		} 
		
		return out_car; //将离开的车的信息返回 

} 


//3.3 当停车场满的时候,接下来的车就应该停到便道上了,本质上是入队列,只需动rear即可 
void in_street(Street *street,Parking_Car *car){
	street->car[street->rear++] = *car;
} 

//3.4 从便道上到停车场中,因为要按照顺序出去 
Parking_Car out_street(Street *street){
	return street->car[street->front++];
} 

//4. 对数据的展示
//4.1 对停在停车场内的车进行数据的展示
void display_lot(Parking_Lot *PL){
	for(int i=0;i<=PL->top;i++){
		cout<<"车牌号:"<<PL->car[i].number<<endl;
		cout<<"开始停车时间:"<<PL->car[i].start_time<<endl;
		if(PL->car[i].end_time != -1)
			cout<<"结束停车时间:"<<PL->car[i].end_time<<endl;
	}

} 

//4.2 对在便道中的车进行数据展示 
void display_street(Street *street){
	for(int i=street->front;i<street->rear;i++){ //队列展示是从front 到 rear ,而不是从0到rear 
		cout<<"车牌号:"<<street->car[i].number<<endl;
		cout<<"开始停车时间:"<<street->car[i].start_time<<endl;
		if(street->car[i].end_time != -1)
			cout<<"结束停车时间:"<<street->car[i].end_time<<endl;
	}
}

//4.3用于展示最后要输出的信息
void display(Parking_Lot *PL,Street *street){  //分别对停车场,便道和离开的车进行数据展示 
	cout<<"停车场:"<<endl; 
	display_lot(PL);
	cout<<endl;
	cout<<"便道:"; 
	display_street(street);
	cout<<endl<<endl; 
} 

int main(){
	Parking_Lot *PL = init_PL();
	Street *street = init_Street(); 
	Parking_Car car_leave[10]; //用于记录离开车辆的信息 
	int jj = 0;//用于记录离开的车辆信息的索引 
	char sta;
	string num;
	int time;
	while(1){
		cin>>sta>>num>>time;
		//进入 
		if(sta == 'A'){
			//1.初始化一个车的数据
			Parking_Car *car = init_PC(sta,num,time);
			//2.判断停车场是否车满,满则停到便道
			if(PL->top == MAX_SIZE-1){ 
				in_street(street,car);
			} 
			else{
				//2.1 未满则停到停车场内,但首先要判断便道上是否有车,如果没车就直接停到停车场内,如果有车就先让便道上的车进停车场 
				if(street->rear == 0){//表示便道上没车 
					in_parking(PL,car); 
				} 
				else{
					//Parking_Car car1 = out_street(street);
					//car1.start_time = time; //此时进入到停车场需要更换进入时间 
					in_parking(PL,car); //将便道上的头部进入停车场
					//in_street(street,car);//并将新来的车进入到便道上 
				}
			}

		}
		//离开 
		else if(sta == 'D'){
			//1.有车从停车场出去 
			car_leave[jj] = out_parking(PL,num,time);
			//2.此时如果便道上有车就会从便道进入到停车场
			if(street->rear != 0){//说明便道上有车
				//3.所以要从便道出去,进入到停车场 
				Parking_Car car2 = out_street(street);
				car2.start_time = time; //此时进入到停车场需要更换进入时间 
				in_parking(PL,&car2); //将便道上的头部进入停车场
			} 
			
			
			jj += 1;//离开一辆加一次; 
//			cout<<"车牌号:"<<car.number<<endl;
//			cout<<"开始停车时间:"<<car.start_time<<endl;
//			cout<<"结束停车时间:"<<car.end_time<<endl;

			
		}
		//停止 
		else if(sta == 'E')
			break;
			
	}
	
	//展示数据
	display(PL,street);  //是最后在停车场和便道的车量信息
	cout<<"离开的车辆信息:"<<endl; 
	for(int i=0;i<jj;i++){
		cout<<"车牌号:"<<car_leave[i].number<<endl;
		cout<<"开始停车时间:"<<car_leave[i].start_time<<endl;
		cout<<"结束停车时间:"<<car_leave[i].end_time<<endl;
		cout<<"停车时间"<< car_leave[i].end_time-car_leave[i].start_time<<endl;
		cout<<endl;
	} 

	return 0;
}

运行结果:
只要最后是以E 0 0 结尾就可以进行统计了
image-20230326194444889

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值