1、停车场模拟管理程序的设计与实现 试验三 停车场模拟管理程序的设计与实现 本实验的目的是进一步理解线性表的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。 一、 问题描述 设停车场只有一个可停放几辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达的先后顺序依次排列,若车场内停满几辆车,则后来的汽车只能在门外的便道上等候,一旦停车场内有车开走,则排在第一辆车即可进入;当停车场内某辆车要离开时,由于停车场是狭长通道,在它之后开入的车辆必须先退出停车场为它让路,待该车辆开出大门,计算其停放时间并收费,为他让路的车辆再按原次序进入车场。在这里假设汽车不
2、能从便道上开走,试设计一个这样的停车场模拟管理程序。为了以下描述的方便,停车场用“停车位”进行叙述,停车场的便道用“便道”进行叙述。 二、 数据结构设计 1、为了便于区分每辆汽车,需要记录汽车的车牌号和历史编号,并且记录其入场、出场时间,所以为汽车定义一个新的类型CAR,具体定义如下: typedef struct{ //汽车信息 string license_plate;//车牌号码 int h; time_t timei; time_t timeo; }CAR; 2、由于车位是一个狭长通道,所以不允许两辆汽车同时出入停车位,当有车来到要进入停车位时也要顺次停
3、放,当某辆车要离开时,比他后到的车要暂时离开停车位,而且越后到的车越先离开停车位,显然这和栈的“先出后进"特点吻合,所以可以使用一个栈来描述停车位。 由于停车位只能停放有限的几辆车,而且为了便于停车场的管理,要为每个车分配一个固定的编号,不妨设1、2、3、4和5(可利用数组下标),分别表示停车位的1车位、2车位、3车位、4车位和5车位,针对这种使用一个顺序栈比较方便,具体定义如下: typedef struct{ //停车位 int STOP[MAX_STOP]; //每个停车位汽车的信息 int top; //用来指示栈顶空间的静态指针 }S
4、TOPPING; 3、当停车场的停车位上都已经停满了汽车,又有新的汽车到来时要把它调度到便道上,便道上的车辆要按照进入便道的顺序顺次存放在便道上,为便道上的每一个位置也分配一个固定的编号,当有车从停车位上离开后,便道上的第一辆汽车就立即进入停车位上的某一个车位,由于问题描述中限制了便道上的汽车不能从便道上开走,即便道上的汽车只有在停车位上停放过之后才能离开停车场,这样越早进入便道的汽车越早进入停车位,而且每次进入停车位的汽车都是处于便道“最前面”的汽车,显然,这和队列的“先进先出”的特点相吻合,所以,这里使用一个顺序队列来描述便道,可以利用数组的下标表示便道的位置,具体定义如下: type
5、def struct{ //便道 int PAVE[MAX_PAVE];//各个汽车信息的村存储 int front,rear;//头指针和尾指针 }PAVEMENT; 4、当某辆车要离开停车场的时候,比他后进停车场的车要为它让路,而且当它开走之后让路的车还要按照原来的的停放顺序再次进入停车位的某个车位上,为了完成这项功能,再定义一个辅助栈,停车位中让路的车依次“压入”辅助栈,待提出开走请求的车开走后再从辅助栈的栈顶依次“弹出”到停车位中。对辅助栈也采用顺序栈,具体定义与停车位栈类似,如下: typedef struct{ //临时位置 int
6、 BUFF[MAX_STOP]; int top; }BUFFER; 当然,辅助栈直接利用在2中定义的类型STOPPING也可以的。 由于程序的各种函数要对这些数据进行操作,而且每次操作的结果都要动态地反映到以上数据结构中,所以在程序设计时使用以上新类型定义的变量都采用全局变量的形式。 三、 函数(功能)设计 1、本程序从总体上分为4个大的功能模块,分别为程序功能介绍和操作提示模块、汽车进入停车位的管理模块、汽车离开停车位的管理模块和查看停车场停车状态的查询模块。具体功能描述如下: (1)程序功能介绍和操作提示模块:此模块给出程序欢迎信息,介绍本程序的功能,并给出程序功能所对应
7、的键盘操作提示,具体屏幕显示如下所示: ●●●●●●●●●欢迎使用本程序●●●●●●●●●● 本程序为停车场的模拟管理程序,有车到来时请按【C】键; 然后根据屏幕提示进行相关操作,有车要走时请按【L】键; 然后根据屏幕提示进行相关操作,要查看车位请按【V】键. 本程序为停车场的模拟管理程序,要退出程序请按【Q】键; 函数原型为: void welcome(); (2)汽车进入停车位的管理模块:此模块用来登记停车位的汽车的车牌号和对该车的调度过程并修改汽车的状态,其中调度过程要以屏幕信息的形式反映给用户来指导用户对车辆的调度。例如,当前停车位上1、2、3车位分别停放着牌照为JF0
8、01、JF002、JF003的汽车,便道上无汽车,当牌照为JF004的汽车到来后屏幕应给出如下提示信息: 牌照为JF004的汽车停入停车位的4号车位! 函数原型为: void come(); 此函数还要调用其他对于栈和队列的基本操作。 (3)汽车离开停车位的管理模块:此模块用来为提出离开停车场的车辆做调度处理,并修改相关车辆的状态,其中调度过程要以屏幕信息的形式反馈给用户来指导用户对车辆的调度,当有车离开停车场后应该立刻检查便道上是否有车,如果有车的话立即让便道上的第一辆车进入停车位。例如,当前停车位上1、2、3、4和5车位分别停放着牌照为JF001、JF002、JF003、JF00
9、4和JF005的汽车,便道上的1和2位置分别停放着牌照为JF006和JF007的汽车,当接收到JF003要离开的信息时,屏幕应给出如下提示信息: 牌照为JF0005的汽车暂时从停车位开出; 牌照为JF0004的汽车暂时从停车位开出; 牌照为JF0003的汽车从停车场的3号停车位开走; 牌照为JF0004的汽车从临时停车位回到3号停车位; 牌照为JF0005的汽车从临时停车位回到4号停车位; 牌照为JF0006的汽车从便道开到5号停车位; 函数原型为: void leave(); 此函数还要调用其他对于栈和队列的基本操作。 (4)查看停车场状态的查询模块:此模块用来在屏幕上显
10、示停车位和便道上各位置的状态,例如,当前停车位上1、2、3、4和5车位分别停放着牌照为JF001、JF002、JF003、JF004和JF005的汽车,便道上的1和2位置分别停放着牌照为JF006和JF007的汽车,当接受到查看指令后,屏幕上应显示: 停车位的情况: 1车位--——JF001 2车位—-——JF002 3车位————JF003 4车位——--JF004 5车位————JF005 便道的情况: 1位置————JF006 2位置———-JF007 函数原型为: void display(); 此函数还要调用其他对于栈和队列的基本操作。 2、以上4个总体功能
11、模块要用到的栈和队列的基本操作所对应的主要函数如下表: 函数原型 函数功能 STOPPING init_stopping() 初始化停车位 BUFFER init_buff() 初始化辅助栈 PAVEMENT init_pavement() 初始化便道队列 int car_come(int pos) 汽车进入停车位 int car_leave(int pos) 汽车从停车位开走 int stop_to_buff(int pos) 汽车从停车位临时开走 int buff_to_stop(int pos) 汽车从临时停车位回到停车位 int pave_to_sto
12、p(int pos) 汽车从便道开到停车位 其他函数定义和说明请参照源代码. 3、由于函数应该随时处理用户所提出的操作请求,所以在主函数中用一个DO…WHILE循环结构随时监控键盘的所有按键操作,遇到相应的按键都转到对应的函数继续运行,运行完该函数继续监控键盘按键,如此往复,知道接受到“退出”指令程序才能结束,部分编码如下: 7 welcome(); char key; key=getchar(); while((key!=’Q’)&&(key!=’q’)) { if(key==’C'||key==’c') { come(); w
13、elcome(); } else if(key=='L'||key==’l’) { leave(); welcome(); } else if(key=='V’||key=='v') { display(); welcome(); } key=getchar(); } cout<<"本程序已结束!"<〈endl; 四、 界面设计 本程序的界面力求简洁、友好,每一步需要用户操作的提示以及每一次用户操作产生的调度结果都以中文的形式显示在屏幕上,使用户对要
14、做什么和已经做了什么一目了然。文字的表达精炼、准确。 五、 编码实现(见附录) 六、 运行与测试 对于测试的设计注重所定义的数据结构的边界以及各种数据结构共存的可能性。例如: 1、连续有7辆车到来,车牌号分别为F001、JF002、JF003、JF004、JF005、JF006和JF007,前5辆车应该进入停车位1-5车位,第6 辆车和第7辆车应停入便道的1和2号位置上。 2、1中的情况发生,让车牌号为JF003的汽车从停车场开走,应显示JF004和JF005的让路动作和JF006从便道到停车位的动作. 3、随时检查停车位和便道的状态,不应该出现停车场有空位而便道上还有车的情况.
15、 4、其它正常操作的一般情况. 5、程序容错性测试,当按键输入错误时是否有错误提示给用户知道用户正确操作,并作出正确处理保证程序正常运行。 经过反复的测试运行和测试,程序的容错性能良好,界面简洁友好,运行稳定可靠,符合实际操作规范,基本达到了模拟停车场管理的要求。 七、 实验完成后的思考 1、通过本实验熟练掌握了栈和队列的定义和使用方法,对使用C++语言编码来验证数据结构的理论知识有了更深层次的理解,达到了实验目的。 2、通过在设计过程中的讨论和思考,对使用现有知识利用计算机来解决现实生活中的实际问题树立了信心,对软件工程思想和模块化程序设计思想有了比较清晰地理解,为今后的程序设计
16、奠定了一定的心理和技术上的准备。
3、由于时间仓促和个人能力有限,程序中还有一些需要完善的地方,例如,界面不具有图形化,不能利用鼠标操作等。
附:源程序代码
#include
17、 time_t timeo; }CAR; int c=1; //车辆历史编号 CAR car[MAX]; typedef struct{ //停车位 int STOP[MAX_STOP]; int top; }STOPPING; typedef struct{ //便道 int PAVE[MAX_PAVE]; int front,rear; }PAVEMENT; typedef struct{ //临时位置 int BUFF[MAX_STOP]; int top
18、 }BUFFER; //***************************************************↑数据类型↑************************************************************ STOPPING init_stopping() { STOPPING stopping; stopping。top=-1; return stopping; } STOPPING s; //初始化停车位 BUFFER init_buff() //初始化辅助栈 {
19、 BUFFER buff; buff.top=—1; return buff; } BUFFER b; PAVEMENT init_pavement()//初始化便道队列 { PAVEMENT pavement; pavement。front=-1; pavement.rear=-1; return pavement; } PAVEMENT p; int car_come(int pos) //汽车进入停车位 { s.STOP[++s。top]=car[pos].h; car[pos]。timei=time(NU
20、LL);
cout〈<”车牌号为 "<〈car[pos].license_plate〈〈" 的汽车进入停车场的 "<〈s。top+1<<" 号停车位;"〈〈endl;
return 1;
}
int car_leave(int pos) //汽车从停车位开走
{
s.top—-;
car[pos].timeo=time(NULL);
cout<<”车牌号为 "<〈car[pos]。license_plate<<" 的汽车从停车场的 "〈
21、 "〈〈car[pos]。timeo — car[pos].timei<<" 小时,收费 "〈〈car[pos].timeo-car[pos]。timei<〈” 角;"< 22、 buff_to_stop(int pos) // 汽车从临时车位回到停车位
{
s.STOP[++s。top]=car[pos]。h;
b。top--;
cout<〈"车牌号为 "<〈car[pos].license_plate〈〈" 的汽车从临时停车位回到 "〈〈s。top+1<〈" 号停车位;”<〈endl;
return 1;
}
int pave_to_stop(int pos) //汽车从便道开到停车位
{
s.STOP[++s。top]=car[pos]。h;
car[pos].timei=ti 23、me(NULL);
p。front++;
cout<〈”车牌号为 ”<〈car[pos]。license_plate〈〈" 的汽车从便道开到 "<〈s.top+1<<” 号停车位;”〈〈endl;
return 1;
}
//**********************************************************↑基本操作函数↑*************************************************
void come() //汽车进停车道或便道
{
cout〈<”输 24、入车牌号:";
cin〉〉car[c]。license_plate;
car[c]。h=c;
if(s.top〈4)
{
car_come(c);
}
else
{
p.PAVE[++p。rear]=car[c].h;
cout〈〈p.PAVE[p。rear]< 25、
cout〈〈”您要开走几号车位的汽车:”;
cin〉〉out;
int i;
if(out-1<=s.top)
{
i=s。top;
while(i〉out-1)
{
stop_to_buff(s。STOP[i]);
i——;
}
car_leave(s。STOP[out-1]);
while(b。top!=-1)//临时栈是否有车
{
buff_to_stop(b。BUFF[b.top]);
}
if(p。front!=p。rear)//便道是否有车
{
pave_to_sto 26、p(p。PAVE[p.front+1]);
}
}
else
cout<<"该车位无车!"< 27、便道的情况:”<〈endl;
while(n!=p。rear) //输出便道的的停车情况
{
cout〈〈m〈<"位置————"<〈car[p.PAVE[n+1]].license_plate〈 28、*******
void welcome()
{
cout<〈"●●●●●●●●●欢迎使用本程序●●●●●●●●●●"< 29、buff();
p=init_pavement();
welcome();
char key;
key=getchar();
while((key!=’Q’)&&(key!='q'))
{
if(key=='C’||key=='c’||key==’L’||key==’l’||key=='V'||key==’v')
{
if(key==’C'||key==’c’)
{
come();
welcome();
}
else
if(key==’L'||key==’l')
{
leave();
welcome();
}
else
if(key==’V’||key=='v’)
{
display();
welcome();
}
key=getchar();
}
else
{
key=getchar();
cout〈<”输入错误!请输入【C】【L】【V】【Q】中的一个(不区分大小写):"<〈endl;
}
}
cout〈<”本程序已结束!"<






