停车场问题实验报告

1718190643631

课程设计名称: 数据结构与算法课程设计
专 业 班 级 : XXXX
学 生 姓 名 : XXX/XXX /XXX /XXX
学 号 : XXXXXXXXXXX/XXXXXXXXXXXX
             XXXXXXXXXXX/XXXXXXXXXXXX
指 导 教 师 : XX/XXX
课程设计时间: XXXX年X月XX日 至 XXXX年X月XX日
目录

一、实验构想与规划

  对于本实验,我们采用栈和队列来模拟停车场和便道,当车进入停车场时需要进入最里面的车位,当停车场的车位满时,则考虑将后进入的车辆进入到临时便道(队列)。当车离开停车场时,则需要将该车前已被占满的车位中的车辆转移到暂存空间(栈)中,然后将该车移走之后,再将暂存空间中的车辆转移到停车场中。当车辆离开时计算进入时间与离开时间之间的差,按照一分钟0.1元来计算最后所收的金额。对于未进入停车场的便道上的车,未进入就要离去,则不收取停车费用,流程图如下图1-1,图1-2:

8b762dcb9657f44f3c239b83ccce2d3

图1-1 车辆进入流程图

f45696092ed0ae08f8721649cb5993e

图1-2 车辆离开流程图

(一)实验内容:

  1.设计停车场管理系统的数据结构:包括车辆信息的存储、停车位息的存储等,停车场和暂存空间的栈,便道的队列。

  2.实现停车场管理系统的各个功能模块:包括车辆的进出管理、停车位的分配管理等。

  3.设计测试用例:模拟不同场景下的车辆进出情况,测试系统的性能,稳定性和各类测试数据能否正常通过等。

  4.进行实验并收集数据:记录系统运行的各项指标,如运行时间、内存消耗、时间复杂度、空间复杂度等。

(二)实验步骤:

  1.设计停车场管理系统的数据结构和功能模块。

  2.编写代码实现系统功能。

  3.编写测试用例并进行测试。

  4.记录和分析实验结果。

  5.优化系统设计和代码实现。

(三)实验环境:

  1.编程环境:选择合适的C语言编程环境,Visual Studio等。

  2.操作系统:实验可在Windows系统下进行。

  3.资源准备:保证系统运行所需的资源充分。

(四)实验评估:

  1.定性评估:评估系统功能的完整性和稳定性。

  2.定量评估:通过测试数据分析系统性能指标,如运行时间、内存消耗等。

   3.对比实验结果并总结结论。

(五)实验细节处理:

  1.要保证停车场的长度有限且可变的,就需要宏定义一个maxsize来表示停车场的空间大小,在头部修改大小更加方便。

  2.要保证只有一个大门可进出,根据情况满足FILO的特性,则需要用到栈 的数据结构。

  3.可以运用链式队列来定义便道使得增删更加方便,增加了代码的方便性。

  4.若要将便道里面的车驶入停车场中,则需要先按照队列的先进先出的特点,将便道里面的车辆驶入停车场里面。

  5.要计算车辆停留时间的金额总和,则需要将离开时间与驶入时间做差,按照每分钟0.1元的价格收费。

二、软件代码与说明

  本程序共设计三个抽象数据类型分别表示停车场栈、通道车辆结点和便道队列。

//用顺序栈来定义停车场
typedef struct{
	Car data[maxsize];
	int Top;
}SeqStack;

//用链队列定义便道
typedef struct node{
	Car data;
	struct node *next;
}QueueNode;

//通道队列
typedef struct{
	QueueNode *front;
	QueueNode *rear;
}LinkQueue;

(一)停车场功能函数:

//汽车抵达
void Car_In(SeqStack*S,LinkQueue*q);
//汽车离开
void Car_Out(SeqStack*S,LinkQueue*q); 
//打印停车场车辆信息
void GetPark(SeqStack *s);
//显示当前停车场运营状态
void GetStatus(SeqStack* s, LinkQueue* q);
//打印便道车辆信息
void GetWait(LinkQueue *q);
//打印车的栈的位置
void ParkingLot(SeqStack *s);
//检查停车场内有无该车辆 
int SearchParking(SeqStack* p, Car c);
//便道模拟界面 
void WaitingRoad(LinkQueue *q);

(二)队列操作函数:

//返回队列的元素个数
int CountQueue(LinkQueue *q);
//出队列 离开便道(出队)
Car deQueue(LinkQueue *q);
//队列操作函数 //初始化
LinkQueue* InitQueue();
//判断队列是否为空
bool QueueEmpty(LinkQueue *q);

(三)栈操作函数:

//返回栈的元素个数
int CountStack(SeqStack *s);
//初始栈(停车场)
SeqStack* InitStack();
//离开停车场(出栈)
Car PopStack(SeqStack*S);
//进入停车场(入栈)
void PushStack(SeqStack*S,Car x);

(四)主函数:

//主函数
int main(){
	SeqStack *S = InitStack();
	LinkQueue *q = InitQueue();

	//开始界面
	system("title 停车场管理系统");
	system("mode con cols=60 lines=35");//设置窗口大小 
	//字体颜色
	color(11);

	int index = 1;
	while(index){
		MainMenu();
		char c = _getch();
		switch(c){
			case 'A':
				Car_In(S,q);
				//程序暂停和清空控制台
				system("pause");
				system("cls");
				break;
			case 'B':
				Car_Out(S,q);
				//程序暂停和清空控制台
				system("pause");
				system("cls");
				break;
			case 'C':
				GetStatus(S,q);
				//程序暂停和清空控制台
				system("pause");
				system("cls");
				break;
			case 'D':
				GetPark(S);
				//程序暂停和清空控制台
				system("pause");
				system("cls");
				break;
			case 'E':
				GetWait(q);
				//程序暂停和清空控制台
				system("pause");
				system("cls");
				break;
			case 'Z':
				printf("\n欢迎再次使用STRANGEX-03停车场管理系统,再见!");
				index = 0;
				return 0;
			default:
				printf("请输入正确的字母:");
				//程序暂停和清空控制台
				system("pause");
				system("cls");
		}
	}
}

  汽车抵达:若停车场未满则输入车牌号、抵达时间直接进入,若停车场已满输入信息后将车停入便道;这一过程将停车场以栈的形式展现。

//汽车抵达
void Car_In(SeqStack*S,LinkQueue*q){
	Car x;
	printf("请输入您的车牌号以及抵达时间(eg:U8588 2 15):");
	scanf("%s %d %d",x.id,&x.t1.h,&x.t1.m);
	if(S->Top == maxsize-1){
		x.loc2 = ++i;//便道被占用位置加一
		enQueue(q,x);   ////////////////////
		printf("停车场已满,麻烦您进入便道位置 %d 等待\n",x.loc2); 
	}//停车场已满进入便道 
	else{
 	x.loc1 = S->Top + 2;//停车场被占用位置加一
 	PushStack(S,x);
	printf("成功进入停车场,您的位置为 %d \n",x.loc1); 
}	
}

  汽车离开:以队列模拟车场外的便道,若停车场没有车辆直接返回程序;若停车场有车且要退出的车辆在最外面,则直接退出且算出所需费用;若退出车辆后面有车且便道无车,则需要后面的车为将要退出的车辆让路且算出所需费用;若退出车辆后面有车且便道有车,则后面的车为将要退出的车辆让路且车辆退出后且算出所需费用,让路车辆与便道车辆依次进入停车场。

//汽车离开
void Car_Out(SeqStack*S,LinkQueue*q){
	Car x,t,fir;
	int flag = 0;
	if(S->Top == -1){
		printf("停车场内未有停车车辆\n");
		return ;
	}
	if(S->Top == maxsize-1 && QueueEmpty(q) )
	{
			printf("停车场车辆已停满\n");
			printf("便道上没有车辆\n");
		    //fir = deQueue(q);  // 便道有车
			//flag = 1;
	}
	else if(S->Top == maxsize-1 &&  !QueueEmpty(q))
	{
			printf("停车场车辆已停满\n");
			printf("便道上有车辆\n");
		    fir = deQueue(q);  // 便道有车
			flag = 1;
	}
	SeqStack*Temp = InitStack();//临时栈
	printf("请输入汽车车牌号以及离开时间(eg:U8588 3 15):");
	scanf("%s %d %d",x.id,&x.t2.h,&x.t2.m); 
	if(!SearchParking(S,x)){
	printf("车牌号错误,未发现该停车车辆\n");
	return; 
}
	while(strcmp(x.id,S->data[S->Top].id)!=0){
		t = PopStack(S);
		printf("车牌号为%s的车让路\n",t.id);
		PushStack(Temp,t);
	}//有车辆离开,其他车辆需要按顺序让路 
	
	t = PopStack(S);

	t.t2.h = x.t2.h;
	t.t2.m = x.t2.m;
	float per;
	per = (t.t2.h-t.t1.h)*60 + (t.t2.m-t.t1.m);//停车总时长 
	int  t1,t2;
	if (t.t2.m >= t.t1.m)
	{
		t2 = t.t2.m - t.t1.m;
		t1 = t.t2.h - t.t1.h;
	}
	else {
		t2 = t.t2.m + 60 - t.t1.m;
		t1 = t.t2.h - t.t1.h - 1;
	}//考虑借位 
	
	printf("车牌号为%s的车辆开出\n",t.id);
	
	while(Temp->Top!=-1){
		t = PopStack(Temp);
		t.loc1 = S->Top + 1 ; 
		printf("车牌号为%s的车辆返回停车位\n",t.id);
		PushStack(S,t); 
	}//车辆开出后,让位车辆按照原有顺序回到停车位置 
	
	//考虑便道等候车辆 
	if(flag){
		PushStack(S,fir);
		fir.loc1 = S->Top+1;   // fir.loc1 = S->Top+1;
		printf("车牌号为%s的车辆进入停车场\n",fir.id); 
		
		flag--;
		i--; // 便道车位变化
	}
	
	printf("本次停留时间为 %d 小时 %d 分钟,共计 %.2lf 元\n",t1,t2,per*price);
}

  显示当前停车场运营状态

//显示当前停车场运营状态
void GetStatus(SeqStack* s, LinkQueue* q)
{
	printf("\n※当前功能模块:[C]显示当前停车场运营状态\n");
	printf("-------------------------------------------------------\n");
	printf("停车场共有%d个车位,当前空余车位为%d,便道上共有%d辆车在等待\n", maxsize, maxsize - CountStack(s), CountQueue(q));
	printf("-------------------------------------------------------\n");
	printf("\n");
	return;
}

  打印停车场车辆信息:通过ParkingLot函数将停车场的车辆信息以及它们的具体排布情况显示出来。

//打印停车场车辆信息
void GetPark(SeqStack *s)
{
	printf("\n※当前功能模块:[D]打印停车场内的车辆信息\n");
	printf("-------------------------------------------------------\n");
	ParkingLot(s);
	printf("-------------------------------------------------------\n");
	printf("\n");
}

  打印便道车辆信息:通过waitingRoad函数将便道上车辆的信息与具体的排布情况显示出来。

//打印便道车辆信息
void GetWait(LinkQueue *q){
	printf("\n※当前功能模块:[E]打印便道上的车辆信息\n");
	printf("-------------------------------------------------------\n");
	WaitingRoad(q); 
	printf("-------------------------------------------------------\n");
	printf("\n");
}

  打印车的栈的位置,输出停车场中车的位置,将栈结构更直观的体现出来。

//打印车的栈的位置
void ParkingLot(SeqStack *s){
	printf("    @ @ @ @ @ @ @       ↑\n");
	for(int i=0;i<maxsize;i++){
		printf("    @ ");
		if(i<CountStack(s)){
			printf("车辆%s",s->data[i].id);
			printf(" @");
		}
		else{
			printf("          @");
			
		}
		if(i==0){
			printf("       北");
		}
		else if(i==maxsize-2){
			printf("       ↓");
		}
		else if(i==maxsize-1){
			printf("       南");
		}
		else if(i==maxsize/2-1){
			printf("  停车场示意图");
		}
		printf("\n");
	}
}

  便道模拟界面,输出便道中车的位置,将队列结构更直观的体现出来。

//便道模拟界面 
void WaitingRoad(LinkQueue *q){
	
	printf("        ");
	for(int i=0;i<CountQueue(q);i++){
		printf("@ @ @ @ @ @ ");
	}
	printf("@ @\n");
	printf(" 出口 ← ");
	QueueNode *car=q->front;
	int k=0;
	if(car!=NULL){
		while(car->next!=NULL){
			printf(" | 车辆%s",car->data.id);
			car=car->next;
		}
		printf(" | 车辆%s | ",car->data.id);
	}
	else {
		printf("   ");
	}
	printf(" ← 入口     便道示意图\n");
	printf("        ");
	for(int i=0;i<CountQueue(q);i++){
		printf("@ @ @ @ @ @ ");
	}
	printf("@ @\n");
}

三、实验结果图表及讨论

  顺利进入主界面,在主界面有六个对应按钮,如图3-1。

a41680c600030264c38f1eb73aa9f7a

 

图3-1 主界面

  实现停车进入功能(第一个按钮),输入车辆的牌号、到达时间,若停车场还存在空位,将车辆停入停车场同时反馈出车辆所停位置,如图3-2; 若停车场已停满,车辆将进入便道等待并且反馈出在便道所处位置,如图3-3。

6bce9ad752aa5ad4f37f469afc8f076

 

图3-2 车辆进入停车场

574e60b91e37ec5426f400a11926da9

 

图3-3 车辆进入便道

  实现车辆离开功能(第二个按钮),输入车辆的牌号、离开时间,若车辆处于停车场的最南侧则直接退出停车场并且打印出停车时长与所需金额,如图3-4;若车辆后面存在车辆且便道上无车,则需其他车辆为其让路退出,让路车辆依次再次进入停车场,打印出停留时间与所需金额,如图3-5;若车辆后面存在车辆且便道上有车,则需其他车辆为其让路退出,让路车辆与便道的第一辆车辆依次再次进入停车场,打印出停留时间与所需金额,如图3-6。

e6b2dcdd370d9344335ea6a1eb9a8ff

 

图3-4 停车时长与金额

7db6f9effbee2c2d5743188a4ca17c1

 

图3-5 车辆让路退出

9c51dc2cd178973adb791d99646456c

 

图3-6 车辆让路退出且便道车进入停车场

  查阅停车场运营信息(第三个按钮),显示出停车场总共车位与剩余车位以及便道车辆的等待情况,如图3-7。

b1f3c7647b25ec82ce95e4ab758e3bf

 

图3-7 显示停车场的运营状态

  查阅停车场的停车情况(第四个按钮),显示出车辆停占的具体情况,如图3-8。

e6113dc39d0a5050bbe0e72612cee7d

 

图3-8 打印停车场内的车辆信息

  查阅便道的车辆情况(第五个按钮),显示出车辆便道具体等待状况,如图3-9。

31be1d3b9dca519f5783eb3763db701

 

图3-9 打印便道上的车辆信息

四、结论及心得

  数据结构是一门重要的专业基础课,通过这次课程设计使我了解了语言程序设计的思想,并且掌握了程序设计的基本方法为后续课程打下了坚实的基础。同时,这次课程设计又是一次实践性较强的知识应用。在对我进行程序设计基础理论与技术技巧能力训练的同时,更加培养了我解决实际问题的编程能力。

  在设计过程中,首先要解决的是与同学的合作,搂下来分工与协商,共同探讨,大家取长补短,认清自己的不足之处和薄弱环节,加以弥补和加强,要做出一个好的程序就要有不懈追求的精神和对理想崇高的追求,有一种不完成不罢休的精神。c语言作为一种高级编程语言具有力便灵活的特点,适合各种类型的软件开发,为我们以后学习单片机非常有用。

  在设计初期,根据题目的要求和所学的知识车库中的车辆是先进后出的,是栈结构,便道上的车辆是先进先出的,是一个队列,结构很明显,应用栈和队列来解决这个问题,这样也可以起到一个连续记录数据的功能,完成设计要求的任务。

  在实际的编写停车场管理系统时,我需要设计高效的算法来实现车辆的进出、停车位的分配等功能。通过学习算法知识,我可以不断优化系统的性能,提高系统的效率和稳定性;同时错误处理和异常情况处理很重要:在实际运行的停车场管理系统中,可能会遇到各种异常情况和错误。通过学习错误处理和异常处理机制,我可以更好地处理这些情况,保证系统的安全和稳定运行。

  总之,这次课程设计挖掘了我们潜在的能力,也使我们对编程更加有兴趣,为以后的学习打下了良好的基础。

五、组员工作分配与贡献百分比

组员姓名

工作内容

贡献比

XXX

1.独立完成代码构思,设计,实现及后续问题的修改

2.绘制总体框架和流程图

3.后续实验报告的整合,格式的修改,报告内容局部修改和最后实验报告的定稿。

4.最终PPT的局部微调和定稿。

40%

XX

1.撰写实验报告(实验构想与规划)

2.PPT撰写(实验结果及分析)

3.PPT撰写(遇到的困难与解决方法)

4.实验报告的要求修改

5.测试代码是否符合预期结果

6.找到并更正一个.Car-In函数中的一行错误代码

20%

XXX

1. 撰写实验报告(心得体会)

2. 撰写实验报告(实验结果图表及讨论)

3. 参考文献的收集([5]~[6])

4. PPT撰写(实验结果及分析的内容编写)

5. PPT的最后的修改完善

20%

XXX

1. 报告撰写(主要内容)

2. 报告撰写(任务要求)

3. 参考文献收集([1]~[4])

4. 报告撰写(代码整合:栈操作、队列操作函数)

5. 报告整合

6. 制作PPT(1-7页)

20%

 

六、参考文献

1.李春葆.数据结构与算法教程[M].清华大学出版社,2005.

2.严蔚敏.数据结构(C语言版).清华大学出版社,2021.

3.www.csdn.net.

4.托马斯·科尔曼、查尔斯·雷瑟尔森、罗纳德·李维斯特、克利福德·斯坦.算法导论.麻省理工学院出版社,2009.

5.甘勇,李晔,卢冰.C语言程序设计[M].北京:中国铁道出版社,2014.

6.耿国华.数据结构--C语言版描述.高等教育出版社,2006.

posted @ 2024-07-19 16:07  咖啡里的茶i  阅读(63)  评论(0)    收藏  举报