一、需求分析
1.每一组输入数据包括:汽车“到达”或“离去”信息、汽车牌照号码以
及到达或离去的时刻。
2.输出信息:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用。
3.测试数据
设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3,20),(‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。其中:‘A’表示到达;‘D’表示离去;‘E’表示输入结束。
4.【选作内容】:两个栈共享空间,思考应开辟数组的空间是多少?
5.【选作内容】:停放在便道上的汽车也收费,收费标准比停放在停车场的车。
https://wenku.baidu.com/view/efbb3919bf64783e0912a21614791711cc797918
实习二 栈、队列和递归算法设计
题目:停车场管理 实习时间:2012/10/14
一、需求分析
1.每一组输入数据包括:汽车“到达”或“离去”信息、汽车牌照号码以
及到达或离去的时刻。
2.输出信息:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用。
3.测试数据
设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3,20),(‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。其中:‘A’表示到达;‘D’表示离去;‘E’表示输入结束。
4.【选作内容】:两个栈共享空间,思考应开辟数组的空间是多少?
5.【选作内容】:停放在便道上的汽车也收费,收费标准比停放在停车场的车。
二、设计
二、 1. 设计思想
二、 (1)存储结构
以栈模拟停车场,以队列模拟车场外的便道。栈以顺序结构实现,队 列以链表结构实现。
不需另设一个栈,栈顶空间临时停放为将要离去的汽车让路而从停车场退出来的汽车,栈用顺序存储结构实现。输入数据按到达或离去的时刻有序。栈中每个元素表示一辆汽车,包含三个数据项:汽车的牌照号码停车时刻和进入停车场的时刻。
(2)主要算法基本思想
按照顺序(两栈共享空间)栈和链式队列的基本操作,初始化一个栈和一个队列,若车辆进站,先判断车站是否满,未满就进车站,满了就进过道:若车辆离开,先在站中找到该车辆,再判断队列是否空,若非空则将车从过道进到站中并记录进站的时间;若不进行车辆的进出则终止程序。
2. 设计表示
(1)函数调用关系图
main→StackPush→QueueAppend→QueueAd→StackPop→QueueGet
(2)函数接口规格说明
int StackPush(SeqStack *S,LQueue *Q,Carmessage Carx)//若车站S未满,则Carx的信息入栈;若车站S满,则Carx的信息入队列Q;
int QueueAppend(LQueue *Q,Carmessage Carx) //Carx的信息入队列Q
int QueueAd(LQueue *Q,int lh,int lm) //队列Q中排队等候入栈的车辆,载入入栈时间 lh,lm
int StackPop(SeqStack *S,LQueue *Q,Carmessage *Carx)// 若车站S非空,则Carx的信息出栈;若此时队列Q中有车等候入栈,则将该车入栈S。
int QueueGet(LQueue *Q,Carmessage *Cary) //队列非空,将Carx的信息从Q中出队列。
3. 实现注释 (即各项功能的实现程度)
(1)可根据需要修改栈的大小(n项),只需将MaxStackSize 的值改2*n-1;
(2)若输入的字母不是A,D,E,则提示重新输入。
(3)若栈中无输入的车牌号,则输出“无此车”,重新输入。
4. 详细设计 (即主要算法的细化。略,见上课笔记)
【1】 int StackPush(SeqStack *S,LQueue *Q,Carmessage Carx)//停车场的入栈函数
{
if(S->top1>=(MaxStackSize+1)/2) //车场停满 ,停到过道 即入队列
QueueAppend(Q,Carx);
else //车辆未满,入栈 S,
{
S->Car[S->top1].alhour=0;
S->Car[S->top1].alminute=0;
S->Car[S->top1].ahour=Carx.ahour;
S->Car[S->top1].aminute=Carx.aminute;
S->Car[S->top1].number=Carx.number;
S->top1++;
return 1;
}
【2】int QueueAppend(LQueue *Q,Carmessage Carx) //入队列函数
{
LQNode *p;
p=(LQNode *)malloc(sizeof(LQNode));
p->Car.number=Carx.number;
p->Car.ahour=Carx.ahour;
p->Car.aminute=Carx.aminute;
p->Car.alhour=Carx.alhour;
p->Car.alminute=Carx.alminute;
p->next=NULL;
Q->count++;
if(Q->rear!=NULL)Q->rear->next=p;
Q->rear=p;
if(Q->front==NULL)Q->front=p;
return 0;
}
【3】 int StackPop(SeqStack *S,LQueue *Q,Carmessage *Carx)//停车场的出栈函数
{
int n,m;
int kaiguan=0; //用于判断是否找到相应车牌号的车
Carmessage Cary;
if(S->top1<=0)return 2;
for(n=S->top1;S->top1>0;S->top1--) //寻找出栈的车牌号 if(S- >Car[S->top1-1].number==Carx->number)
{
Carx->ahour=S->Car[S->top1-1].ahour;//记录被删除车信息
Carx->aminute=S->Car[S->top1-1].aminute;
Carx->alhour=S->Car[S->top1-1].alhour;
Carx->alminute=S->Car[S->top1-1].alminute;
for(;n>S->top1;n--,S->top2--)
{
S->Car[S->top2].ahour=S->Car[n-1].ahour;
S->Car[S->top2].aminute=S->Car[n-1].aminute;
S->Car[S->top2].number=S->Car[n-1].number;
S->Car[S->top2].alhour=S->Car[n-1].alhour;
S->Car[S->top2].alminute=S->Car[n-1].alminute;
}
for(S->top1--;S->top2<MaxStackSize;S->top1++,S->top2++)//转移进//开出
{
S->Car[S->top1].ahour=S->Car[S->top2+1].ahour;
S->Car[S->top1].aminute=S->Car[S->top2+1].aminute;
S->Car[S->top1].number=S->Car[S->top2+1].number;
S->Car[S->top1].alhour=S->Car[S->top2+1].alhour;
S->Car[S->top1].alminute=S->Car[S->top2+1].alminute;
}
S->top2--;
}
S->top1--; //开出一辆
kaiguan=1; //找到该车
break;
}
if(kaiguan==0&&S->top1==0&&S->top1<n){S->top1=n;return 2;}
if(S->top1==(MaxStackSize-1)/2&&Q->front!=NULL)//判断是否有车等候进站
{
QueueGet(Q,&Cary);
S->Car[S->top1].ahour=Cary.ahour;
S->Car[S->top1].aminute=Cary.aminute;
S->Car[S->top1].number=Cary.number;
S->Car[S->top1].alhour=Cary.alhour;
S->Car[S->top1].alminute=Cary.alminute;
S->top1++;
}
return 1;
}
【4】int QueueGet(LQueue *Q,Carmessage *Cary) //出队列
{
Cary->number=Q->front->Car.number;
Cary->ahour=Q->front->Car.ahour;
Cary->aminute=Q->front->Car.aminute;
Cary->alhour=Q->front->Car.alhour;
Cary->alminute=Q->front->Car.alminute;
Q->front=Q->front->next; //队列头指针后移
Q->count--;
return 0;
}
【5】int QueueAd(LQueue *Q,int lh,int lm) //排队等候入栈的车辆,载入入栈时间
{
Q->front->Car.alhour=lh;
Q->front->Car.alminute=lm;
return 0;
}
三、调试分析
1.调试过程中遇到的主要问题是如何解决的;
调试过程中存在少许C语言的基础语法错误,经独立仔细观察和调试修改正确,最大的难题是栈和队列的指针移动的条件需细心考虑,其在循环中的移动情况要考虑充分,以及地址在多个函数调用时的变化。在自己独立多次修改下,终于完成。
2.对设计和编码的回顾讨论和分析;
在增加选作内容时,意识到在代码删改过程中,牵一发而动全身的纷繁复杂性,需要多次反复查看和检查。在今后的编程过程中要更注重代码整体设计的提纲记录,用更多的注释。
3.时间和空间复杂度的分析;
【1】入栈函数: 时间O(n),空间O(1)
【2】入队列函数:时间O(n),空间O(n)
【3】出栈函数:时间O(n^2),空间O(1)
【4】出队列函数:时间O(1),空间O(1)
4.改进设想;
此次实习需要设计的算法较少,主要是一些栈和队列的基本操作和各函数之间的调用条件(该条件或有更简洁的表示)。其它地方暂无修改办法。
5.经验和体会等。
多动手编程,才能熟练灵活的掌握C语言基础知识,才能更好的理解掌握数据结构的精髓。从而避免基础语法错误,让代码变得更简洁高效。如此才能准确高效的解决问题。在今后的编程过程中要更注重代码整体设计的提纲记录,用更多的注释。
四、用户手册(即使用说明)
仅需按照提示输入大写字母和数字(输入的时间格式按12:12的时刻格式)即可。
五、运行结果
运行环境:C-free
【1】设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3,20),(‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。其中:‘A’表示到达;‘D’表示离去;‘E’表示输入结束。
【选作内容】:停放在便道上的汽车也收费,收费标准比停放在停车场的车。
若输入非’A’’D’’E’,则提示重新输入。
【2】又增选做内容,
【选作内容】:两个栈共享空间,思考应开辟数组的空间是多少?//2*n-1
【选作内容】:停放在便道上的汽车也收费,收费标准比停放在停车场的车。
【内容】若栈中无出栈的车牌号,输出提示,重新输入。
六、源程序清单
https://wenku.baidu.com/view/efbb3919bf64783e0912a21614791711cc797918