栈和队列:停车场管理

一、程序运行环境

1、操作系统: Windows 10 X64

2、IDE:Visual Studio 2019

二、问题描述

在这里插入图片描述

三、程序设计思路

(1)确定解决问题所使用的数据结构:以栈分别模拟停车场和为给要离去的汽车让路而从停车场退出来的汽车,以队列模拟车场外的便道。栈以顺序存储结构实现,队列以链式结构实现。

(2)定义Car结构体,用于实现栈的顺序存储结构,包括汽车号码、状态(到达/离开)、到达时间、抵达时间以及在停车场内停留时间,以便于后续相关计算。

struct  Car
{
	int number;
	char aord;
	int atime;
	int dtime;
	int dutime;
};

(3)定义结构体WCar,用于实现队列的链式存储结构,包括汽车号码、状态(到达/离开)、到达时间、抵达时间、以及指向下一个结点的指针。

struct  WCar
{
	int number;
	char aord;
	int atime;
	int dtime;
	WCar* next;
};

(4)分别实现栈和队列的基本功能:定义Stack类,实现初始化、入栈、出栈、查找等功能。定义Queue类,实现初始化、入队、出队等功能。

class Stack
{
private:
	Car* base, * top;
	int count;
public:
	Stack()
	{		
		count = 0;
		base = new Car[n];
		top = base;
	}
	int num()
	{
		return count;
	}
	int find(int x)
	{
		int i = 0;
		Car* p=base;
		while (p->number != x)
		{
			p++;
			i++;
		}
		return i;
	}
	int getatime(int x)
	{
		return base[x].atime;
	}
	int Push(Car e)
	{
		top->aord = e.aord;
		top->atime = e.atime;
		top->dtime = e.dtime;
		top->dutime = e.dutime;
		top->number = e.number;
		top++;
		count++;
		return count;
	}
	Car Pop()
	{
		Car p;
		count--;
		top--;
		p = *top;
		return p;
	}
};

class Queue
{
private:
	WCar* head,*rear;
public:
	Queue()
	{
		WCar* p = new WCar;
		p->number = 0;
		p->next = NULL;
		head = rear=p;
	}
	int Inqueue(WCar a)
	{
		WCar* p = new WCar;
		p->aord = a.aord;
		p->atime = a.atime;
		p->dtime = a.dtime;
		p->next = NULL;
		p->number = a.number;
		rear->next = p;
		rear = p;
		head->number ++ ;
		return head->number;
	}
	Car Dequeue(Car a)
	{
		WCar* q;
		Car p;
		if (head == rear)exit(0);
		q = head->next;
		head->next = q->next;
		p.aord = 'A';
		p.atime=p.dtime = a.dtime;
		p.dutime = 0;
		p.number = q->number;
		delete q;
		head->number--;
		return p;
	}
	int Getnumber()
	{
		return head->number;
	}
};

(5)准备工作完成后,接下来梳理相关算法:首先判断输入的是‘A’或’D‘,若输入’A’,判断是否超过停车场容量n,超过通过Inqueue函数入队列,反之通过Push函数入栈;若输入‘D’,通过find函数找到该辆汽车所处位置以及进入停车场的时间,从而计算出停留时间,停车场内该辆汽车后的汽车出栈,进入另一栈,待该辆汽车出栈后另一栈汽车再依次入栈,并队列中第一辆汽车通过Dequeue函数出队入栈。

int main()
{
	char c;
	Stack s1, s2;
	Queue h;
	Car a; WCar b;
	cin >> c >> c >> a.aord>>c>>c;
	while (a.aord == 'A' || a.aord == 'D')
	{
		if (a.aord == 'A')
		{
		
			if (s1.num() <n)
			{
				cin >> a.number>>c>>a.atime>>c;
				a.dtime = a.atime;
				a.dutime = 0;
				s1.Push(a);
				cout << "汽车到达停车场位置:"<<s1.num()<<endl;
				
			}
			else
			{
				b.aord = 'A';
				cin >> b.number >> c >> b.atime >> c;
				b.dtime = b.atime;
				b.next = NULL;
				cout<< "汽车到达便道位置:"<<h.Inqueue(b)<<endl;//入队列
				
			}
		}
		if (a.aord == 'D')
		{
			Car b;
			cin >> a.number >> c >> a.dtime >> c;
			
			int i = s1.find(a.number);
			a.dutime = a.dtime - s1.getatime(i);//得到该车进入的时间
			while (s1.num() != (i + 1))
			{
				b=s1.Pop();
				s2.Push(b);
			}
			cout << "在停车场内停留时间:"<<a.dutime<<" "<<"需交停车费:"<<a.dutime<<endl;
			s1.Pop();
			while (s2.num() != 0)
			{
				b = s2.Pop();
				s1.Push(b);
			}
			if (h.Getnumber()!=0&& s1.num()<n)s1.Push(h.Dequeue(a));//队列第一位进入栈
		}
		
		cin >> c >> c >> a.aord >> c>>c;
	}
}

四、注意事项

①判断循环结束:应该先在输入字母时进行判断,若为’E’,则结束输入。在每一次循环结束后,也需要再对输入字母进行一次判断。

②判断便道上是否有汽车要进入:需要同时满足停车场栈内有一个空位且队列中有汽车,若没有对这两个同时进行限制的话,结果将出现错误。不必担心停车场栈内多个空位而队列中有汽车问题,因为队列中有汽车的前提是停车场栈内已满。

if (h.Getnumber()!=0&& s1.num()<n)s1.Push(h.Dequeue(a));

五、程序运行截图

在这里插入图片描述

  • 3
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
问题描述:利用堆栈和队列实现一个停车场管理系统 基本要求: 设停车场是一个可以停放n辆汽车的狭长通道,且只有一个大门可以供车辆进出。车辆按到达停车场时间的早晚依次从停车场最里向大门口处停放(最先到达的第一辆车放在停车场的最里面)。如果停车场已放满n辆车,则后来的车只能在停车场大门外的便道上等待,一旦停车场内有车开走,则排在便道上的第一辆车就进入停车场停车场内如有某辆车要开走,在它之后进入停车场的车都必须先退出停车场为它让路,待其开出停车场后,这些车辆再依原来的次序进场。每辆车在离开停车场时,都应根据它在停车场内停留的时间长短交费。如果停留在便道上的车未进停车场就要离去,允许其离去,不收停车费,并且仍然保持在便道上等待的车辆次序。编制一程序模拟该停车场管理。车辆的信息包括:车牌号、汽车到达/离去标志、到达/离去时刻等。按照从终端读入的数据序列进行模拟管理。每辆车需要三个数据,其中车辆数据为:A表示到达,D表示离去,E表示程序结束。车辆牌照为整型数据。进场或离场时间同样为整型数据。对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。 停车场管理系统主要实现以下几个功能: (1)根据车辆到达停车场到车辆离开停车场时所停留的时间进行计时收费。 (2)该程序设计能够通过车牌号能查到该车辆在停车场或便道中的位置。 (3)当有车辆从停车场离开时,等待的车辆按顺序进入停车场停放。实现停车场的调度功能。 [测试数据] (A,1,1) (A,2,2) (A,3,3) (A,4,4) (A,5,5) (D,2,7) (A,1,8) (A,4,9)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值