银行业务模拟问题描述链表和队列.docx
《银行业务模拟问题描述链表和队列.docx》由会员分享,可在线阅读,更多相关《银行业务模拟问题描述链表和队列.docx(18页珍藏版)》请在冰豆网上搜索。
银行业务模拟问题描述链表和队列
摘要
问题描述:
客户业务分为两种。
第一种是申请从银行得到一笔资金,即取款或借款。
第二种是向银行投入一笔资金,即存款或还款。
银行有两个服务窗口,相应的有两个队列。
客户到达银行后先排第一个队。
处理每个客户业务时,如果属于第一种,且申请额超出银行现存资金总额而得不到满足,则立即排入第二队等候,直至满足时才离开银行,否则业务处理完后立即离开银行。
每接待完一个第二种业务的客户,则顺序检查和处理(如果可能)第二个队列的客户,对能满足的申请者予以满足,不能满足者重新排到第二个队列的队尾。
注意,在此检查过程中,一旦银行资金总额少于或等于刚才第一个队列中最后一个客户(第二种业务)被接待之前的数额,或者本次已将第二个队列检查或处理了一遍,就停止检查(因为此时已不可能还有能满足者)转而继续接待第一个队列的客户。
任何时刻都只开一个窗口。
假设检查不需要时间。
营业时间结束时所有客户立即离开银行。
写一个上述银行业务的事件驱动模拟系统,通过模拟方法求出客户在银行内逗留的平均时间。
关键字:
队列链表取款借款存款还款驱动模拟系统平均时间
目录
1.引言-4-
2.需求分析-4-
3.概要设计-5-
1.单链表的抽象数据类型定义为:
-5-
4.详细设计-6-
1、程序结构图-6-
2、程序流程图-6-
3、算法设计-7-
5.测试结果-12-
6.调试分析-13-
7.设计体会-13-
8.结束语-13-
9.参考文献-14-
10.附录-14-
1.引言
随着数据处理的不断进步和计算机网络的迅速发展,银行业务的处理速度也越来越快,熟悉运用队列和链表编写程序和掌握现代信息系统的开发方法也显得尤为重要。
所以对于计算机专业的学生来说熟练掌握队列的运用是每个学生的必备本领。
本次课程设计就是以银行业务模拟问题为模型,运用C语言和数据结构结合队列和链表开发的系统。
关键字:
C语言数据结构队列链表
2.需求分析
基本功能:
银行的办理业务模式。
在与传统的各个窗口排队的方式相比现在的打卡号的方式更加的科学和合理,对于这种方法的一种模拟就是本软件的要求。
在不同的时间来不同的人,在未知的情况下来的多少人和银行办理业务的资源的冲突,还有不会因为个人的办理业务的时间长短而影响到其他人办理业务的时间问题。
对于银行流水线业务的模拟。
利用等候区来缓冲在窗口使用为满时候的资源和使用的冲突。
在窗口结束工作以后排在队列最前端的顾客去进行办理业务。
输入输出形式:
对于次题目是模拟银行运做的系统,而且时间是随即产生的,关于输入方式。
可以不用太多。
也可以没有。
个人可以在做界面的时候输入对应的选项。
而输出相应的结果。
必要输出:
客户到达时间,客户进入的窗口。
客户办理的业务。
测试数据:
营业时间为8小时,其他模拟量自行设定。
测试数据为时间产生的随机数对于模拟银行中的时间和业务敷值。
关键字:
基本功能输入输出测试数据
3.概要设计
1.单链表的抽象数据类型定义为:
ADTeventlist{
数据对象:
D={qi|qi∈ElemSet,i=1,2,……,n,n>=o}
数据关系:
R={〈qi-1,qi>|qi-1,qi∈D,i=2,3,……,n}
队列的抽象数据类型定义:
ADTQueue{
数据对象:
D={ai|ai∈ElemSet,i=1,2,……,n,n>=o}
数据关系:
R={〈ai-1,ai>|ai-1,ai∈D,i=2,3,……,n}
基本操作:
Initqueue(linkqueue&q)
操作结果:
构造一个空的队列q;
Initlist(linklist&ev)
操作结果:
构造一个空的链表ev;
push(queue&q,intd)
初始条件:
队列数组已存在
操作结果:
在队尾插入一个元素e
pop(queue&q)
初始条件:
队列已存在
操作结果:
获取队列q的队头
service*front(queue&q)
初始条件:
队列已存在
操作结果:
返回队首元素
service*back(queue&q)
初始条件:
队列已存在
操作结果:
返回队尾元素
service*searchAndDel(queue&q,intm)
初始条件:
队列已存在
操作结果:
在队里寻找可处理元素
voidputMoney()
操作结果:
处理存款事件
voidgetMoney()
操作结果:
处理取款事件
voidarrive()
初始条件:
初始化操作完毕
操作结果:
处理客户到达事件
}ADT
2.本程序包含五个模块:
①主程序模块:
Voidmain(){接受命令;处理命令;}
②事件链表表单元模块——实现链表的抽象数据类型;
③队列单元模块——实现队列的抽象数据类型;
④事件结点结构单元模块——定义链表的结点结构;
⑤队列结点结构单元模块——定义队列的结点结构;
各模块之间的调用关系如下:
主程序模块—〉链表、队列表单元模块—>队列、链表结点结构单元模块。
4.详细设计
1、该程序结构图
图3-1
2、该程序流程图
图3-2
3、算法设计:
客户信息
structservice{
intnum;//客户号
stringtype;//到达或离开
intbeginTime;
intendTime;
intmoney;//正数为存款,负数为取款
service*next;
};
队列
structqueue{//队列
service*head;
service*rear;
};
入队算法
voidpush(queue&q,intd){//插入元素d为Q的新的队尾元素
service*temp=newservice;
temp->money=d;
temp->next=NULL;
if(NULL==q.head){//队列为空,初始化
q.head=temp;
q.rear=temp;
}//if
else{//队列不为空,插入元素d
q.rear->next=temp;
q.rear=q.rear->next;
}//else
}
出队算法
voidpop(queue&q){//若队列不空,出队列函数
service*temp;
temp=q.head;
if(NULL==q.head->next)
q.head=q.rear=NULL;
else
q.head=q.head->next;
deletetemp;
}
返回队首元素算法
service*front(queue&q){//返回队首元素
returnq.head;
}
返回队尾元素算法
service*back(queue&q){//返回队尾元素
returnq.rear;
}
处理事件算法
service*searchAndDel(queue&q,intm){//在对列中寻找可处理元素
service*sign=q.head;//标记头节点
service*temp;
while(NULL!
=q.head){
if((-(q.head->money))if(q.head==q.rear){
temp=q.head;
q.head=q.rear=NULL;
returntemp;
}//if
else{//队首元素出列
temp=q.head;
q.head=q.head->next;//首节点后移一位,返回原首节点
returntemp;
}//else
}//while
else{//队首元首不能被处理
if(q.head==q.rear){}
else{//首节点移到队列尾部
q.rear->next=q.head;
q.rear=q.rear->next;
q.head=q.head->next;
q.rear->next=NULL;
}//else
}//else
if(q.head==sign)//队列循环一周时停止
returnNULL;
}
returnNULL;
}
客户到达事件
voidarrive(){/*"到达"函数随机产生顾客,进入队列一
产生到达事件进入事件队列*/
push(fq,(rand()%(2*dealMoney)-dealMoney));//随机产生顾客加入第一队列
back(fq)->beginTime=currentTime;
back(fq)->num=number;
push(eq,(back(fq)->money));//将产生事件加入事件队列
back(eq)->beginTime=currentTime;
back(eq)->type="到达";
back(eq)->num=number;
++number
}
处理存款或还款事件算法
voidputMoney(){//存款函数
total+=front(fq)->money;//更新资金总额
push(eq,front(fq)->money);//加入事件队列离开
back(eq)->type="离开";
back(eq)->num=front(fq)->num;
back(eq)->endTime=(front(fq)->beginTime+rand()%dealTime+1);
++counter;//更新客户总数
totalTime+=(back(eq)->endTime-front(fq)->beginTime);//更新逗留时间
pop(fq);//删除第一队列第一个业务
currentTimeOfDeal=back(eq)->endTime;
state=0;
}
处理取款或借款事件算法
voidgetMoney(){//取款函数
if((-fq.head->money)>total){//资金短缺加入第二队列
push(sq,front(fq)->money);
back(sq)->beginTime=front(fq)->beginTime;
back(sq)->num=front(fq)->num;
pop(fq);
}//if
else{
total+=back(fq)->money;
push(eq,front(fq)->money);//加入事件队列离开
back(eq)->type="离开";
back(eq)->num=front(fq)->num;
back(eq)->endTime=(front(fq)->beginTime+rand()%dealTime+1);
back(eq)->beginTime=0;
currentTimeOfDeal=back(eq)->endTime;
++counter;//更新客户总数
totalTime+=(back(eq)->endTime-back(fq)->beginTime);//更新逗留时间
pop(fq);//删除第一队列第一个业务
state=0;
}//else
}
voidfindAndDeal(){//在队列中寻找可处理元素,对其进行处理
while((temped=searchAndDel(sq,total))&&NULL!
=temped){//查找可处理取款
total+=temped->money;//更新资金总额
push(eq,temped->money);//加入事件队列训离开
back(eq)->type="离开";
back(eq)->num=temped->num;
randomTemp=rand()%dealTime+1;
back(eq)->endTime=currentTime+randomTemp;
currentTimeOfDeal+=randomTemp;
++counter;//更新客户总数
totalTime+=(back(eq)->endTime-temped->beginTime);//更新逗留时间
deletetemped;//删除节点
temped=NULL;
}
state=0;
}
5.测试结果
初始界面:
图5-1
模拟界面:
图5-2
6.调试分析
1、我开始没有处理系统时间,即直接使用随机生成的客户到达时间,经查阅资料才知道,原来分钟用ti/60显示,秒用ti%60显示即可。
2、变成过程中犯了一个极其简单的错误,把栈和队列竟然弄反了,在运行结果不对的情况下很难发现错误,花了我好长时间才找出来,我真是糊涂啊。
7.设计体会
本次课程设计我最大的体会是:
编程能力怎么样要看能不能用编程来解决实际生活当中的问题,简单说就是理论联系实际。
开始接触这个题目的时候(银行业务模拟)根本不知从何下手,银行业务怎么和编程联系得上呢?
后来通过上网了解一些实例后,慢慢的一步步上手,等完成以后才知道原来真的可以用编程来解决一些实际当中的问题的。
看来以后还要多多接触这样的问题,来提高自己的实际能力。
8.结束语
这个程序是在C-Free5.0版本下完成的。
使用时只需直接双击exe文件即可。
9.参考文献
1、严蔚敏吴伟民著数据结构(C语言版)清华大学出版社2010
2、谭浩强著C程序设计(第三版)清华大学出版社2005
10.附录
#include
#include
#include
usingnamespacestd;
inttotal;//初始时银行现存资金总额
intcloseTime;//营业结束时间
intarriveTime;//两个到达事件之间的间隔上限
intdealTime;//客户之间交易的时间上限
intdealMoney=5000;//交易额上限
intcurrentTime=0;//当前时间
inttotalTime=0;//客户逗留总时间
intcounter=0;//客户总数
intnumber=1;//初始客户序列号
structservice{
intnum;//客户号
stringtype;//到达或离开
intbeginTime;
intendTime;
intmoney;//正数为存款,负数为取款
service*next;
};
structqueue{//队列
service*head;
service*rear;
};
voidpush(queue&q,intd){//插入元素d为Q的新的队尾元素
service*temp=newservice;
temp->money=d;
temp->next=NULL;
if(NULL==q.head){//队列为空,初始化
q.head=temp;
q.rear=temp;
}//if
else{//队列不为空,插入元素d
q.rear->next=temp;
q.rear=q.rear->next;
}//else
}
voidpop(queue&q){//若队列不空,出队列函数
service*temp;
temp=q.head;
if(NULL==q.head->next)
q.head=q.rear=NULL;
else
q.head=q.head->next;
deletetemp;
}
service*front(queue&q){//返回队首元素
returnq.head;
}
service*back(queue&q){//返回队尾元素
returnq.rear;
}
service*searchAndDel(queue&q,intm){//在对列中寻找可处理元素
service*sign=q.head;//标记头节点
service*temp;
while(NULL!
=q.head){
if((-(q.head->money))if(q.head==q.rear){
temp=q.head;
q.head=q.rear=NULL;
returntemp;
}//if
else{//队首元素出列
temp=q.head;
q.head=q.head->next;//首节点后移一位,返回原首节点
returntemp;
}//else
}//while
else{//队首元首不能被处理
if(q.head==q.rear){}
else{//首节点移到队列尾部
q.rear->next=q.head;
q.rear=q.rear->next;
q.head=q.head->next;
q.rear->next=NULL;
}//else
}//else
if(q.head==sign)//队列循环一周时停止
returnNULL;
}
returnNULL;
}
boolstate=1;//用于判断是否有窗口在处理
intcurrentTimeOfDeal=0;
inttheArriveTime=0;
queueeq;//事件队列
queuefq;//队列一
queuesq;//对列二
//初始化三个队列
voidarrive(){/*"到达"函数随机产生顾客,进入队列一
产生到达事件进入事件队列*/
push(fq,(rand()%(2*dealMoney)-dealMoney));//随机产生顾客加入第一队列
back(fq)->beginTime=currentTime;
back(fq)->num=number;
push(eq,(back(fq)->money));//将产生事件加入事件队列
back(eq)->beginTime=currentTime;
back(eq)->type="到达";
back(eq)->num=number;
++number;
}
voidputMoney(){//存款函数
total+=front(fq)->money;//更新资金总额
push(eq,front(fq)->money);//加入事件队列离开
back(eq)->type="离开";
back(eq)->num=front(fq)->num;
back(eq)->endTime=(front(fq)->beginTime+rand()%dealTime+1);
++counter;//更新客户总数
totalTime+=(back(eq)->endTime-front(fq)->beginTime);//更新逗留时间
pop(fq);//删除第一队列第一个业务
currentTimeOfDeal=back(eq)->endTime;
state=0;
}
voidgetMoney(){//取款函数
if((-fq.head->money)>total){//资金短缺加入第二队列
push(sq,front(fq)->money);
back(sq)->beginTime=front(fq)->beginTime;
back(sq)->num=front(fq)->num;
pop(fq);
}//if
else{
total+=back(fq)->money;
push(eq,front(fq)->money);//加入事件队列离开
back(eq)->type="离开";
back(eq)->num=front(fq)->num;
back(eq)->endTime=(front(fq)->beginTime+rand()%dealTime+1);
back(eq)->beginTime=0;
currentTimeOfDeal=back(eq)->endTime;
++counter;//更新客户总数
totalTime+=(back(eq)->endTime-back(fq)->beginTime);//更新逗留时间
pop(fq);//删除第一队列第一个业务
state=0;
}//else
}
service*temped;
intrandomTemp;
voidfindAndDeal(){//在对列中寻找可处理元素,对其进行处理
while((temped=searchAndDel(sq,total))&&NULL!
=temped){//查找可处理取款
total+=temped->money;//更新资金总额
push(eq,temped->money);//加入事件队列训离开
back(eq)->type="离开";
back(eq)->num=temped->num;
randomTemp=rand()%dealTime+1;
back(eq)->endTime=currentTime+randomTemp;
currentTimeOfDeal+=randomTemp;