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

说明:

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


问题描述:

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

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


基本要求:

数据结构推荐:

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

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

功能要求:

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

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

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

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

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

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

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


停车场结构:

数据结构实验-停车场模拟系统_第1张图片


思维导图:



数据结构实验-停车场模拟系统_第2张图片



代码:

头文件:

//假设停车场和候车道都是空的
#include
#include//为了使用getch();
#include //为了string类型用cin,cout
#include 
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  //为了调用时间函数

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;
	}




你可能感兴趣的:(数据结构)