完整word版银行业务模拟数据结构课设C语言版.docx
《完整word版银行业务模拟数据结构课设C语言版.docx》由会员分享,可在线阅读,更多相关《完整word版银行业务模拟数据结构课设C语言版.docx(19页珍藏版)》请在冰豆网上搜索。
完整word版银行业务模拟数据结构课设C语言版
题目:
银行业务模拟(难度系数:
1.3)
[运行环境]
VS
[问题描述]
客户业务分为两种。
第一种是申请从银行得到一笔资金,即取款或借款。
第二种是向银行投入一笔资金,即存款或还款。
银行有两个服务窗口,相应地有两个队列。
客户到达银行后先排第一个队。
处理每个客户业务时,如果属于第一种,且申请额超出银行现存资金总额而得不到满足,则立刻排入第二个队等候,直至满足时才离开银行;否则业务处理完后立刻离开银行。
每接待完一个第二种业务的客户,则顺序检查和处理(如果可能)第二个队列中的客户,对能满足的申请者予以满足,不能满足者重新排到第二个队列的队尾。
注意,在此检查过程中,一旦银行资金总额少于或等于刚才第一个队列中最后一个客户(第二种业务)被接待之前的数额,或者本次已将第二个队列检查或处理了一遍,就停止检查(因为此时已不可能还有能满足者)转而继续接待第一个队列的客户。
任何时刻都只开一个窗口。
假设检查不需要时间。
营业时间结束时所有客户立即离开银行。
写一个上述银行业务的事件驱动模拟系统,通过模拟方法求出客户在银行内逗留的平均时间。
[基本要求]
利用动态存储结构实现模拟,即利用C语言的动态分配函数malloc和free。
[选做内容]
自己实现动态数据类型。
(已作)
1.需求分析
计算来银行办理业务的用户平均逗留时间:
⑴在运行终端控制台进行信息输入:
输入信息包括(信息都为整数):
1.银行拥有的款额取值范围:
[0,正无穷]
2.银行营业时间取值范围:
[0,1440]
3.用户最大交易金额取值范围:
(0,银行拥有款额]
4.俩个用户到达时间的最大值取值范围:
(0,银行营业时间]
5.用户最大交易时间取值范围:
(0,银行营业时间]
⑵在运行终端控制台进行信息输出:
1.每个到达用户的到达时间,编号,要处理的金额,处理时间
2.事件表
3.总用户数
4.总逗留时间
5.平均逗留时间
⑶程序所能达到的功能;
1.输出每个用户的到达时间,编号,要处理的金额,处理时间
2.银行运营过程的全部事件(包括到达事件和离开事件)
3.计算银行运营过程的用户数,总逗留时间,平均逗留时间
⑷三组测试数据:
1.正常情况:
1.银行拥有的款额:
10000
2.银行营业时间:
600
3.用户最大交易金额:
2000
4.俩个用户到达时间的最大值:
20
5.用户最大交易时间:
15
应输出:
25.48
2.极端的情况:
两个到达事件之间的间隔时间很短,而客户的交易时间很长
1.银行拥有的款额:
10000
2.银行营业时间:
600
3.用户最大交易金额:
2000
4.俩个用户到达时间的最大值:
5
5.用户最大交易时间:
100
应输出:
20.0
3.极端的情况:
两个到达事件之间的间隔时间很长,而客户的交易时间很短
1.银行拥有的款额:
10000
2.银行营业时间:
600
3.用户最大交易金额:
2000
4.俩个用户到达时间的最大值:
100
5.用户最大交易时间:
5
应输出:
88.38
源代码如下:
#include
#include
#include
#include
typedefintStatus;
#defineOK1
#defineERROR-1
/*#defineMAXTIME600//定义银行运作时间(单位:
分钟假设一分钟等于一秒)
#defineMAX_TIMEJIANGE5//定义最大时间间隔
#defineMAX_TIMEJIAOYI100//定义最大操作时间*/
typedefstructkehu_event{
//定义客户信息
inthandel_time;//事件处理时间
intmoney;//需要处理的钱数目(负数表示取钱,正数表示存钱)
intNo;//客户的序号
}ElemType;
typedefstructevent{
/*定义事件类型*/
intindex;/*标志变量,1代表到达事件,其余代表离开事件*/
inttime;/*事件发生时间*/
intNo;/*触发该事件的客户序号*/
}event;
typedefstruct{/*定义链表节点*/
eventdata;
structLNode*next;
}LNode,*Link;
typedefstruct{/*定义链表*/
Linkhead,tail;
intlen;
}*LinkList;
LinkListInitLink(){/*初始化链表操作*/
LinkListL=(LinkList*)malloc(sizeof(LNode));
if(L==NULL)returnNULL;
L->head=NULL;
L->tail=NULL;
L->len=0;
printf("链表初始化成功!
!
");
returnL;
};
StatusClearLink(LinkListL){/*链表的清空操作*/
if(L==NULL)returnERROR;
Linkp=L->head;
Linkk=L->head->next;
while(p!
=L->tail)
{
free(p);
p=k;
if(k!
=L->tail)k=k->next;
}
free(p);
L->head=NULL;
L->tail=NULL;
L->len=0;
printf("链表已经清空!
!
");
returnOK;
}
StatusDestoryLink(LinkListL){/*链表的销毁操作*/
if(L==NULL)returnERROR;
ClearLink(L);
free(L);
printf("链表销毁完毕!
!
");
returnOK;
}
StatusInsertLink(LinkListL,evente){/*链表的尾部插入操作*/
if(L==NULL)returnERROR;
Linkp=(Link)malloc(sizeof(LNode));
if(p==NULL)returnERROR;
p->data=e;
p->next=NULL;
if(L->head==NULL){
L->head=p;
L->tail=p;
L->len=1;
}else{
L->tail->next=p;
L->tail=p;
L->len++;
}
//printf("节点插入成功!
!
");
returnOK;
}
StatusLinkTraverse(LinkListL){/*链表的遍历操作*/
if(L==NULL)returnERROR;
Linkp=L->head;
printf("\n遍历结果:
\n");
printf("客户序号:
事件触发时间:
事件类型:
");
printf("\n------------------------------------------------------------");
while(p!
=NULL){
printf("\n%d%d",p->data.No,p->data.time);
if(p->data.index==1){
printf("到达");
printf("\n--------------------------------------------------------------");
}
else{
printf("离开");
printf("\n-------------------------------------------------------------");
}
p=p->next;
}
returnOK;
}
typedefstructLQNode{/*定义队列的节点*/
ElemTypedata;
structLQNode*next;
}LQNode,*QueuePtr;
typedefstruct{/*定义队列*/
QueuePtrfront;
QueuePtrrear;
intlen;
}LQueue;
LQueue*InitQueue(){/*构造一个空队列*/
LQueue*Q=(LQueue*)malloc(sizeof(LQueue));
if(Q==NULL)returnERROR;
Q->front=NULL;
Q->rear=NULL;
Q->len=0;
returnQ;
}
StatusEnQueue(LQueue*Q,ElemTypee){//在队列的队尾插入e
LQNode*p;
p=(LQNode*)malloc(sizeof(LQNode));
if(p==NULL)returnERROR;
p->data=e;
p->next=NULL;
if(NULL==Q->front){
Q->front=p;
Q->rear=p;
Q->len=1;
}
else
{
Q->rear->next=p;
Q->rear=p;
Q->len++;
}
returnOK;
}
StatusDeQueue(LQueue*Q,ElemType*e){
//是队列Q的队头出队并且返回到e
LQNode*p;
if(NULL==Q->front)returnERROR;
p=Q->front;
*e=p->data;
Q->front=p->next;
if(Q->rear==p)Q->rear=NULL;
free(p);
Q->len--;
returnOK;
}
StatusDestoryQueue(LQueue*Q){
/*队列的销毁操作*/
if(Q==NULL)returnERROR;
QueuePtrp=NULL,q=NULL;
p=Q->front;
while(p!
=Q->rear){
q=p->next;
myfree(p);
p=q;
}
free(Q->rear);
returnOK;
}
StatusInsertQueue(LQueue*Q,LQueue*E){
/*将E队列插入到Q队列的前面,并将Q队列作为新的队列释放E*/
if(E==NULL||E->front==NULL)returnERROR;
if(Q==NULL||Q->front==NULL||Q->rear==NULL){
Q->front=E->front;
Q->rear=E->rear;
}else
{
E->rear->next=Q->front;
Q->front=E->front;
}
returnOK;
}
/*-------------------------------------定义需要使用的全局变量--------------------------------------*/
inttotal;/*一天营业开始时银行拥有的款额为10000(元),并且默认取钱只能*/
//inttotal_time=600;/*营业时间为600(分钟)*/
intmax_money;
LQueue*handel_queue=NULL;/*定义第一个队列用于处理业务*/
LQueue*wait_queue=NULL;/*定义第二个队列用于存储等候的客户*/
LinkListevent_link=NULL;/*定义一个事件表*/
intnextTime=0;/*定义一个变量作为下一个客户的随机到达时间*/
intnexthandelTime=0;/*定义一个变量作为正在排队的下一个客户处理时间*/
intkehu_NO=1;/*客户的服务序号*/
ElemType*leave_kehu=NULL;/*定义一个办理完业务要离开的客户变量,用于记录*/
ElemType*search_kehu=NULL;/*定义一个用来存储待处理业务的客户变量*/
/*-------------------------------------------------------------------------------------------------*/
ElemType*mymalloc(intmax_timejiaoyi){
/*动态申请客户节点*/
ElemType*e;
e=(ElemType*)malloc(sizeof(ElemType));
if(e==NULL)return;
e->handel_time=(rand()%max_timejiaoyi)+1;
e->money=(rand()%(2*max_money))-max_money;
e->No=kehu_NO;
kehu_NO++;
returne;
}
Statusmyfree(ElemType*e){
/*动态释放客户节点*/
if(e==NULL)returnERROR;
free(e);
returnOK;
}
/*
Statussuiji_kehu(ElemType*e,intmax_timejiaoyi){
/*随机生成客户信息
mymalloc(e,max_timejiaoyi);
returnOK;
}
*/
ElemType*Arrial_event(inti,intmax_timejiange,intmax_timejiaoyi){
/*用来处理新客户到达事件*/
if(nextTime==i){
printf("当前时间是:
%d\n",i);
nextTime=nextTime+(rand()%max_timejiange)+1;//随机生成下一名客户到达时间,这里可以设置客户到达时间间隔的大小
ElemType*p=NULL;
p=mymalloc(max_timejiaoyi);//到达前面设置的到达时间时,随机生成刚到达用户的信息,包括客户编号,业务处理时间,业务操作钱的数目
event*e=(event*)malloc(sizeof(event));//生成该到达事件的信息节点
e->index=1;
e->No=p->No;
e->time=i;
InsertLink(event_link,*e);//将该到达事件的信息节点加入事件链表
if(nexthandelTime
if(-(p->money)<=total){
nexthandelTime=p->handel_time+i;
total=total+p->money;
EnQueue(handel_queue,*p);
}
else{
EnQueue(wait_queue,*p);
}
}
else{
if(nexthandelTime==0){//第一个进入操作的用户情况
if(-(p->money)<=total){
nexthandelTime=p->handel_time+i;
total=total+p->money;
EnQueue(handel_queue,*p);
}
else{
EnQueue(wait_queue,*p);
}
}elseEnQueue(handel_queue,*p);
}
if(nexthandelTime==0){//第一个进入操作的用户情况
if(-(p->money)<=total){
nexthandelTime=p->handel_time+i;
total=total+p->money;
EnQueue(handel_queue,*p);
}
else{
EnQueue(wait_queue,*p);
}
}
printf("\n客户编号:
%d客户操作需要时间:
%d客户需要处理的钱:
%d银行余额:
%d\n\n\n",p->No,p->handel_time,p->money,total);
returnp;
}
}
Statushandel_event(inti){
/*处理队列事件*/
if(nexthandelTime==i){/*到达下一个客户操作时间时*/
DeQueue(handel_queue,leave_kehu);//将处理完的客户出队,并将客户信息存储在leave_kehu变量中
intlast_money=total-leave_kehu->money;//获取刚离开的客户操作前银行的钱数目
Leave_event(leave_kehu,i);//将离开事件的用户信息存入事件列表中
if(((leave_kehu->money)>0)&&wait_queue->front!
=NULL){
/*如果刚刚离开的用户是存钱或者还钱,并且等待队列不为空*/
intindex=0;//设置标记变量,用以标记等待队列已经查看的客户数目
LQueue*e=InitQueue();//创造出一个可以被满足需求的等待用户组成的队列
intlinshi_total=total;//设置一个临时金额存储空间
while(linshi_total>last_money&&wait_queue->front!
=NULL){//如果当前银行拥有的款额比之前多,进入循环
DeQueue(wait_queue,search_kehu);//将等待队列的队头用户出队
if(-(search_kehu->money)<=linshi_total){
/*如果等待用户的需求可以得到满足*/
EnQueue(e,*search_kehu);//将可满足用户加入等待用户队列
linshi_total=linshi_total+search_kehu->money;
}
else{
EnQueue(wait_queue,*search_kehu);
}
index++;
if(index>=wait_queue->len)break;
}
InsertQueue(handel_queue,e);//将可以满足要求的等待队列并入前面
//nexthandelTime=nexthandelTime+handel_queue->front->data.handel_time;//下一个处理用户时间更新
if(handel_queue->front!
=NULL){
/*如果操作队列不为空*/
while(handel_queue->front!
=NULL&&-(handel_queue->front->data.money)>total)
/*如果无法满足要求*/
{
DeQueue(handel_queue,leave_kehu);
EnQueue(wait_queue,*leave_kehu);
}
if(handel_queue->front!
=NULL){
nexthandelTime=handel_queue->front->data.handel_time+nexthandelTime;//下一位操作客户时间更新
total=total+handel_queue->front->data.money;//银行金钱总额更新
}
}
}else{
/*刚刚离开的用户是取钱或者借钱,或者等待队列为空*/
if(handel_queue->front!
=NULL){
while(handel_queue->front!
=NULL&&-(handel_queue->front->data.money)>total)
{
/*无法满足的用户进入等待队列*/
DeQueue(handel_queue,leave_kehu);
EnQueue(wait_queue,*leave_kehu);
}
if(handel_queue->front!
=NULL){
/*处理队列不为空*/
nexthandelTime=handel_queue->front->data.handel_time+nexthandelTime;
total=total+handel_queue->front->data.money;
}