【问题描述】
设有一个可以停放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 结尾就可以进行统计了