数据结构实验-停车场模拟系统

说明:

在大二小学期,老师布置了一个数据结构实验,小组成员花了大概一周完成了实验,如果代码有bug,望指出,谢谢。


问题描述:

模拟一个停车场系统。停车场根据停车的占地面积进行收费。我们假设一个停车场存在大、中、小三种车型的停车位。当有车辆进入停车场时,登记车的型号,车牌以及时间,并将车停放在停车场内。当取车时,输入车牌号,取出相应的车,并记录现在时间,根据停车时间收取费用。

当停车场满时,在停车场外的一个长度为N的候车道等待进入停车场停车。


基本要求:

数据结构推荐:

1)推荐用二维数组描述停车场的结构

2)推荐用队列描述候车道的结构

功能要求:

用文件保存停车场和候车道的基本数据

停车:可选择车位,输入车牌号,将车的基本信息存入车位中

取车:输入车牌,获取时间,计算费用

查询:在停车时,可以查询停车场的整体情况

空位提示:一旦取车后停车场出现空位,需要将信息传递给候车道。候车道队列出列

满位提示:一旦停车厂位满,则需要在候车道停车,即候车道入队列。

附加难度:有余力的同学可以考虑用图形界面实现停车场的状态显示。


停车场结构:



思维导图:






代码:

头文件:

//假设停车场和候车道都是空的
#include<stdio.h>
#include<conio.h>//为了使用getch();
#include <iostream>//为了string类型用cin,cout
#include <string>
using namespace std;

double parkArea[3] = { 1, 2, 3 };//车位面积
double const priceper = 0.005;//单位时间单位面积停车价格(RMB)
int const maxsize =50;//停车位数量(大中小都有maxsize个停车位),maxsize定义范围为1-100
string kind[3] = { "small", "medium", "big" };//车型
int size[3] = { 0, 0, 0 };//大、中、小车位停的车辆个数,初始化停车位为空
int const N = 11;//每一个候车道能排的车数,最大数量为N-1(根据队列的性质可知)

//定义车结构体
typedef struct CAR
{
	string kind;//车型
	string carID;//车牌
	int parkID;//停车位
	time_t enterTime;//停车开始时间
}Car;


//定义队列
//定义队列结构体
struct QueueCar
{
	Car *que;
	int front;
	int rear;
	int maxsize;
	int sizeinQueue;
};

//初始化
bool Initqueue(QueueCar &s)
{
	s.maxsize = N;
	s.que = new Car[s.maxsize];
	if (!s.que)
	{
		printf("分配失败\n");
		return false;
	}
	s.front = 0;
	s.rear = 0;
	return true;
}

//入队
void enqueue(QueueCar &s, Car item)
{
	if ((s.rear + 1) % s.maxsize == s.front)
		printf("\n候车道已满,欢迎有空光临\n");
	else
	{
		//打开文件(文件不存在会自动新建)
		FILE *fpqueue;
		if ((fpqueue = fopen("D:\\VS2013\\停车场\\queue.1", "wb+")) == NULL){
			printf("Cannot open file strike any key exit!");
			getch();
			exit(1);
		}

		s.rear = (s.rear + 1) % s.maxsize;
		s.que[s.rear] = item;//队尾入元素

		//将候车道数据存入文件
		s.sizeinQueue++;
		fprintf(fpqueue, "%d", s.sizeinQueue);//写入数据

		/*
		//将候车道数据取出
		rewind(fpqueue);
		fscanf(fpqueue, "%d", &s.sizeinQueue);//读出数据
		printf("\n读取候车道文件中...\n");
		printf("您车型的候车道车辆数量:%d\n", s.sizeinQueue);
		*/
		fclose(fpqueue); //关闭文件
		return;
	}
}

//出队
bool outqueue(QueueCar &s, Car &item)
{
	//打开文件(文件不存在会自动新建)
	FILE *fpqueue;//指针名与前面的入队里的文件指针可以不同,只要指向相同的文件即可
	if ((fpqueue = fopen("D:\\VS2013\\停车场\\queue.1", "wb+")) == NULL)
	{
		printf("Cannot open file strike any key exit!");
		getch();
		exit(1);
	}

	if (s.rear == s.front)
	{
		printf("队列为空\n");
	}
	s.front = (s.front + 1) % s.maxsize;
	item = s.que[s.front];

	//将候车道数据存入文件
	s.sizeinQueue--;
	fprintf(fpqueue, "%d", s.sizeinQueue);//写入数据
	
	/*
	//将候车道数据取出
	rewind(fpqueue);
	fscanf(fpqueue, "%d", &s.sizeinQueue);//读出数据
	printf("\n读取候车道文件中...\n");
	printf("\n您车型的候车道车辆数量:%d\n",s.sizeinQueue);
	*/
	fclose(fpqueue); //关闭文件
	return true;
}

//判空
bool isemptyqueue(QueueCar s)
{
	if (s.front == s.rear)
		return true;
	return false;
}


源文件:

//增加功能:用三个队列
#include "1.h"
#include <time.h> //为了调用时间函数

Car car[3][maxsize];
QueueCar smallqueue;
QueueCar mediumqueue;
QueueCar bigqueue;

//获取当地时间
void Calendar(time_t t)
{
	time(&t);
	struct  tm* tminfo;
	tminfo = localtime(&t);
	printf("Date: %04d-%02d-%02d %02d时%02d分%02d秒\n", tminfo->tm_year + 1900,
		tminfo->tm_mon + 1, tminfo->tm_mday, tminfo->tm_hour, tminfo->tm_min, tminfo->tm_sec);
	return;
}

//查询停车场整体情况
void findPark()
{
	printf("剩余小型车停车位:%d  ", maxsize - size[0]);
	printf("剩余中型车停车位:%d  ", maxsize - size[1]);
	printf("剩余大型车停车位:%d\n", maxsize - size[2]);
	printf("剩余小型车候车位:%d  ", N - 1 - smallqueue.sizeinQueue);
	printf("剩余中型车候车位:%d  ", N - 1 - mediumqueue.sizeinQueue);
	printf("剩余大型车候车位:%d\n", N - 1 - bigqueue.sizeinQueue);
	
	//查看停车场所有车的carID,kind和parkID
	FILE *fppark;
	if ((fppark = fopen("D:\\VS2013\\停车场\\park.1", "wb+")) == NULL)
	{
		printf("Cannot open file strike any key exit!");
		getch();
		exit(1);
	}		

	rewind(fppark);
	fread(car, sizeof(Car), 1, fppark);	//读取停车场数据
	printf("\n读取停车场文件中...\n停车场全部车辆信息:\n");
	int flagfile=0;//标志停车场内有无车,默认无车
	for(int i=0;i<3;i++)
	{
		for (int k = 0; k < maxsize;k++)
		{
			if(car[i][k].kind != "0"&&car[i][k].carID != "0")
			{
				printf("carID:%s\tkind:%s\t", car[i][k].carID.c_str(), car[i][k].kind.c_str());
				if (i == 0)//对小型车特殊处理
				{
					if (k < 10)
						printf("parkID:00%d\n", car[i][k].parkID);//显示结果为00*
					else
						printf("parkID:0%d\n", car[i][k].parkID);//显示结果为0**
				}
				else
					printf("parkID:%d\n", car[i][k].parkID);
				flagfile += 1;
			}
		}
	}
	if (flagfile == 0)
		printf("停车场内无车");
	
	fclose(fppark);//关闭文件

	return;
}

//判断停车场是否停满车,规定不同车型只能停在对应车型的车位
bool notFull(string kind)
{
	if (kind == "small")
		return maxsize - size[0];
	else if (kind == "medium")
		return maxsize - size[1];
	else return maxsize - size[2];
}

//停车
void enterCar(QueueCar &q, string kind, string carID)
{
	if (notFull(kind))//有剩余车位
	{
		int i = 0;
		if (kind == "small")
			i = 0;
		else if (kind == "medium")
			i = 1;
		else if (kind == "big")
			i = 2;
		else
		{
			printf("请您输入正确的车型\n");
			printf("程序将退到主菜单......\n");
			return;
		}
		//查找具体剩余的车位是哪些
		printf("剩余车位:\n");
		for (int j = 0; j < maxsize; j++)
		{
			if (car[i][j].kind == "0"&&car[i][j].carID == "0")//Menu函数中已将结构体kind和carID初始化为"0",表示该车位是空着的
			{
				int parkNumber = 100 * i + j;//获取停车位
				if (i == 0)//对小型车特殊处理
				{
					if (j < 10)
						printf("00%d ", parkNumber);//显示结果为00*
					else
						printf("0%d ", parkNumber);//显示结果为0**
				}
				else
					printf("%d ", parkNumber);
			}
		}
		printf("\n请选择车位:");
		int parkID;
		scanf("%d", &parkID);

		int k = 0;
		k = parkID % 100;//作用同上面for循环的j

		//判断parkID是否合法,且车不能停在已经有车的车位
		if (parkID >= 100 * i && parkID < 100 * i + maxsize&&car[i][k].kind == "0"&&car[i][k].carID == "0")
		{
			//打开文件(文件不存在会自动新建)
			FILE *fppark;
			if ((fppark = fopen("D:\\VS2013\\停车场\\park.1", "wb+")) == NULL)
			{
				printf("Cannot open file strike any key exit!");
				getch();
				exit(1);
			}

			car[i][k] = { kind, carID, parkID, time(NULL) };
			printf("进入停车场的时间:  ");
			Calendar(car[i][k].enterTime);
			if (i == 0)//对小型车特殊处理
			{
				if (k < 10)
					printf("请停在 00%d 号车位\n", car[i][k].parkID);//显示结果为00*
				else
					printf("请停在 0%d 号车位\n", car[i][k].parkID);//显示结果为0**
			}
			else
				printf("请停在 %d 号车位\n", car[i][k].parkID);
			size[i]++;//停车场对应车型停车数+1		

			//将停车场数据存入文件
			fwrite(car, sizeof(Car), 1, fppark);
			
			/*
			//将停车场数据取出
			rewind(fppark);
			fread(car, sizeof(Car), 1, fppark);
			printf("\n读取停车场文件中...\n您正操作的车的信息:\n");
			printf("进入停车场的时间:  ");
			Calendar(car[i][k].enterTime);
			printf("carID:%s\tkind:%s\t", car[i][k].carID.c_str(), car[i][k].kind.c_str());
			if (i == 0)//对小型车特殊处理
			{
				if (k < 10)
					printf("parkID:00%d\n", car[i][k].parkID);//显示结果为00*
				else
					printf("parkID:0%d\n", car[i][k].parkID);//显示结果为0**
			}
			else
				printf("parkID:%d\n", car[i][k].parkID);
			*/
			fclose(fppark);//关闭文件
		}
		else//用户选择错误
		{
			printf("sorry,您选择的车位已经有车了或者您输入了不存在的停车位\n");
			printf("程序将退到主菜单......\n");
			return;
		}
	}
	else //若无剩余车位,即停车场满时,则车进入候车道
	{
		if (N - 1 == q.sizeinQueue)//候车道满
		{
			printf("暂无您选择的车位,且候车道已满,欢迎有空再光临\n");
			return;
		}
		else//候车道未满
		{
			printf("暂无您选择的车位,请进入您的车型所在候车道排队等待\n");
			Car carinQueue = { kind, carID, 0, time(NULL) };
			enqueue(q, carinQueue);//入候车道
		}
	}
	return;
}

//取车
void leaveCar(string carID)
{
	printf("请输入车牌号:");
	cin >> carID;
	int flag = 0;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < maxsize; j++)
		{
			if (car[i][j].kind == "0"&&car[i][j].carID == "0")//该停车位无车
				continue;
			if (car[i][j].carID == carID)//找到车了
			{
				string kind = car[i][j].kind;
				//打开文件(文件不存在会自动新建)
				FILE *fppark;
				if ((fppark = fopen("D:\\VS2013\\停车场\\park.1", "wb+")) == NULL)
				{
					printf("Cannot open file strike any key exit!");
					getch();
					exit(1);
				}
				time_t leaveTime = time(NULL);//车离开的时间
				printf("离开停车场的时间:  ");
				Calendar(leaveTime);
				printf("共计在停车场停留 %d 秒\t", leaveTime - car[i][j].enterTime);
				printf("总费用为:%.2fRMB\n", priceper*parkArea[i] * (leaveTime - car[i][j].enterTime));
				size[i]--;//停车场对应车车辆数-1

				//将停车场数据存入文件
				fwrite(car, sizeof(Car), 1, fppark);
			
				/*
				//将停车场数据取出
				rewind(fppark);
				fread(car, sizeof(Car), 1, fppark);
				printf("\n读取停车场文件中...\n您正操作的车的信息:\n");
				printf("离开停车场的时间: ");
				Calendar(leaveTime);
				printf("carID:%s\tkind:%s\t", car[i][j].carID.c_str(), car[i][j].kind.c_str());
				if (i == 0)//对小型车特殊处理
				{
					if (j < 10)
						printf("parkID:00%d\n", car[i][j].parkID);//显示结果为00*
					else
						printf("parkID:0%d\n", car[i][j].parkID);//显示结果为0**
				}
				else
					printf("parkID:%d\n", car[i][j].parkID);
				*/
				string leavecarKind = car[i][j].kind;//离开的车的车型

				//将新的该车位的新数据存入文件
				car[i][j].kind = "0";
				car[i][j].carID = "0";
				fwrite(car, sizeof(Car), 1, fppark);
				fclose(fppark);//关闭文件

				//通知候车道
				if (kind == "small")//小型车
				{
					if (!isemptyqueue(smallqueue))//如果候车道有车
					{
						//停车场出现空位,通知候车道		
						Car item;
						printf("请小型车候车道队首车出队,前往咨询处");
						outqueue(smallqueue, item);
						if (item.kind == leavecarKind)
							printf("\n请在咨询处的车进行操作(选菜单):");
					}
				}
				else if (kind == "medium")//中型车
				{
					if (!isemptyqueue(mediumqueue))//如果候车道有车
					{
						//停车场出现空位,通知候车道		
						Car item;
						printf("请中型车候车道队首车出队,前往咨询处");
						outqueue(mediumqueue, item);
						if (item.kind == leavecarKind)
							printf("\n请在咨询处的车进行操作(选菜单):");
					}
				}
				else//大型车
				{
					if (!isemptyqueue(bigqueue))//如果候车道有车
					{
						//停车场出现空位,通知候车道		
						Car item;
						printf("请大型车候车道队首车出队,前往咨询处");
						outqueue(bigqueue, item);
						if (item.kind == leavecarKind)
							printf("\n请在咨询处的车进行操作(选菜单):");
					}
				}
					flag = 1;
					break;//已经取了车,跳车第一层循环
				}
			}
			if (flag == 1)
				break;//已经取了车,跳出第二层循环
		}
		if (flag == 0)//没找到车牌号对应的车
		{
			printf("sorry,您要取的车并未停在贵大停车场,请检查您输入的车牌号是否正确,\n");
			printf("程序将退到主菜单......\n");
		}
		return;
	
}

//菜单
void Menu()
{
	//初始化

	//将全部结构体成员kind和carID初始化为“0”
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < maxsize; j++)
		{
			car[i][j].carID = "0";
			car[i][j].kind = "0";
		}
	}
	//初始化候车道为空
	Initqueue(smallqueue);
	Initqueue(mediumqueue);
	Initqueue(bigqueue);
	system("color 2E");//更改dos窗口背景和前景颜色
	do{
		printf("\n");
		for (int i = 0; i<20; i++)
			printf("*");
		printf("*****欢迎来到**停车场!*****");
		for (int i = 0; i<20; i++)
			printf("*");
		printf("\n");
		printf("1:存入车辆  2:取出车辆  3:查询停车场整体情况  4:退出\n");
		printf("请选择:");
		int key;
		scanf("%d", &key);
		switch (key)
		{
			case 1:
			{

						printf("请分别输入车型(small,medium or big),车牌\n");
						string kind, carID;
						printf("车型(输入车型后请按回车键):");
						cin >> kind;
						printf("车牌:");
						cin >> carID;
						if (kind == "small")
							enterCar(smallqueue, kind, carID);
						else if (kind == "medium")
							enterCar(mediumqueue, kind, carID);
						else
							enterCar(bigqueue, kind, carID);
						printf("\n"); break; }
			case 2:
			{
						string carID;
						leaveCar(carID);
						printf("\n"); break;
			}
			case 3:
				findPark(); printf("\n"); break;

			case 4:
				exit(0); printf("\n"); break;
			default:
			{
						printf("您输入了错误的指示,请您重新输入!\n");
						printf("如果您喜欢输入奇怪的东西,程序可能崩溃且不能进入主菜单\n");
						printf("请您记得崩溃后按ctrl+c结束程序\n");
						printf("程序将退到主菜单......\n");
			}
		}
	} while (true);
	return;
}

	int main()//主函数
	{
		Menu();
		return 0;
	}




本软件是用C++和MFC编写模拟停车场活动的软件。资源包含源代码和exe文件,以及本软件的设计说明书、UML的用例图、序列图、仿真流程图和运行情况总结报告。 大致需求如下: 某企业欲为其专用汽车停车场建设一信息系统,已经调查到的需求如下: 1、 企业为其每个员工均发放一张感应式IC卡,卡上记录了员工号,即该卡的卡号。 2、 在停车场的入口和出口分别安装一个自动栏杆、一台感应式IC卡读入器和一个车辆通过传感器 3、当入场汽车到达入口,IC卡读入器内读出驾驶员的卡上信息,系统根据读出内容检查该卡的合法性:若该卡在合法卡集合,且未被记录于当前场内卡号集合,即为合法卡。这里,合法卡集合有系统预先存储的所有员工卡。若为合法卡,系统命令栏杆自动抬起;汽车通过入口后,入口传感器通知系统发出命令,栏杆自动放下,系统遂将该卡的卡号记录于当前场内卡号集合。若为非法卡,则系统不发出栏杆抬起命令。 4、当一辆汽车到达出口,IC卡读入器读出驾驶员的卡上信息,系统根据读出内容检查该卡是否已被记录于当前场内卡号集合。若已被记录,系统命令栏杆自动抬起;汽车通过出口后,出口传感器通知系统发出命令,栏杆自动放下,系统遂将该卡从当前场内卡号集合删除。若未被记录,系统不发出栏杆抬起命令而发出告警信号,交由出口值班人员处理。 5、若停车场当前没有车位,系统将在入口显示“无车位”信息,此只允许场内的汽车出场。
停车场模拟管理程序的设计与实现 1.设计目的 理解线性表的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。 2.问题描述 设停车场只有一个可停放几辆汽车的狭长通道,只有一个大门可供汽车进出。汽车在停车场内按车辆到达的先后顺序依次排列,若车场内已停满几辆汽车,则后来的汽车只能在门外的便道上等候,一旦停车场内有车辆开走,则排在便道上的第一辆汽车即可进入;当停车场内某辆汽车要开走,由于停车场是狭长的通道,在它之后开入的车辆必须先推出车场为他让路,待车辆开出大门,为他让路的车辆再按原次序进入车场。试设计这样一个停车场模拟管理程序。 3.数据结构设计 (1)为了便于区分每辆汽车并了解每辆车当前所处的位置,需要记录汽车的牌照号码和汽车当前的状态。 (2)为了便于停车场的管理,要为每个车位分配一个固定的编号。 (3)当停车场的停车位上都已停满了汽车,又有新的汽车到来要把它调度到便道上,便道上的车辆要按照进入便道的先后顺序顺次序放在便道上,为便道上的每个位置分配一个固定的编号。当有车从停车位上离开后,便道上的第一辆汽车就立即进入停车位上的某个车位。 (4)当某辆车离开停车场候,比他后进停车位的车要为他让路,而且当他开走之后让路的车还要按照原来的停放次序再次进入停车位的某个车位上,为完成这项功能,定义一个结构体。 4.功能(函数)设计 本程序从总体上分为四个功能模块,分别为: (1)程序功能介绍和操作提示模块 (2)汽车进入停车位的管理模块 (3)汽车离开停车位的管理模块 (4)查看停车场状态的查询模块 5.界面设计 6.编码实现 7.运行与测试 (1)连续有7辆汽车到来,牌照号分别为CF001、CF002、CF003、CF004、CF005、CF006、CF007,前5辆车应该进入停车位1-5车位,第6、7辆车应停入便道的1、2位置上。 (2)上面(1)的情况发生后,让牌照CF003的汽车从停车场开走,应显示CF005、CF004的让路动作和CF006从便道到停车位的动作。 (3)随检查停车位和便道的状态,不应该出现有空位而便道上还有车的情况。 (4)其它正常操作的一般情况。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值