/* * Copyright (c)2015,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名称:实训-银行业务的模拟系统.cbp * 作 者:孙浩瀚 * 完成日期:2015年12月23日 * 版 本 号:v1.0 * 问题描述:设计一个银行业务的模拟系统,模拟银行的业务运行并计算一天中客户在银行逗留的平均时间。 * 输入描述:测试数据 * 程序输出:测试数据 */ #include<iostream> #include<string> #include<time.h> #include <stdio.h> #include <malloc.h> using namespace std; int total; //初始资金 int closeTime; //营业结束时间 int arriveTime; //两个到达事件之间的间隔上限 int dealTime; //客户之间交易的事件上限 int dealMoney=5000; //交易额上限 int currentTime=0; //当前时间 int totalTime=0; //客户逗留总时间 int counter=0; //客户总数 int number=1; //初始客户序列号 struct service{ int num; //客户号 string type; //到达或离开 int beginTime; int endTime; int money; //正数为存款,负数为取款 service *next; }; //队列 struct queue { service *head; service *rear; }; void push(queue &q,int d) //插入元素d为Q的新的队尾元素 { service *temp=new service; temp->money=d; temp->next=NULL; if(NULL==q.head) //队列为空,初始化 { q.head=temp; q.rear=temp; } else //队列不为空,插入元素d { q.rear->next=temp; q.rear=q.rear->next; } } void pop(queue &q) //若队列不空,出队列函数 { service *temp; temp=q.head; if(NULL==q.head->next) q.head=q.rear=NULL; else q.head=q.head->next; delete temp; } service *front(queue &q) //返回队首元素 { return q.head; } service*back(queue &q) //返回队尾元素 { return q.rear; } service *searchAndDel(queue &q,int m) //在队列中寻找可处理元素 { service *sign=q.head; //标记头结点 service *temp; while(NULL!=q.head) { if((-(q.head->money))<m) //队首元素可以处理 { if(q.head==q.rear) { temp=q.head; q.head=q.rear=NULL; return temp; } else //队首元素出列 { temp=q.head; q.head=q.head->next; //首节点后移一位,返回原首节点 return temp; } } 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; } } if(q.head==sign) //队列循环一周时停止 return NULL; } return NULL; } bool state=1; //用于判断是否有窗口在处理 int currentTimeOfDeal=0; int theArriveTime=0; queue eq; //事件队列 queue fq; //队列一 queue sq; //队列二 void arrive()/*"到达"函数随机产生顾客,进入队列一产生到达事件,进入事件队列*/ { 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; } void putMoney() //存款函数 { 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; } void getMoney() //取款函数 { if((-fq.head->money)>total) //资金短缺 加入第二队列 { push(sq,front(fq)->money); back(sq)->beginTime=front(fq)->beginTime; back(sq)->num=front(fq)->num; pop(fq); } 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; } } service *temped; int randomTemp; void findAndDeal() //在队列中寻找可处理元素,对其进行处理 { 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); //更新逗留时间 delete temped; //删除节点 temped=NULL; } state=0; } int main() { printf("\n\n"); printf(" ****************************************\n"); printf(" * *\n"); printf(" * 欢迎进入银行模拟系统 *\n"); printf(" * *\n"); printf(" * 1.开始模拟 0.退出 *\n"); printf(" * *\n"); printf(" ****************************************\n"); int n; printf("请输入您选择"); scanf("%d", &n); while(n==1) { srand((unsigned)time(NULL)); // 初始化随机函数 printf("请输入银行初始存款:\n"); scanf("%d",&total); printf("请输入银行营业时间:\n"); scanf("%d",&closeTime); printf("请输入最大时间间隔:\n"); scanf("%d",&arriveTime); printf("请输入最大的处理时间:\n"); scanf("%d",&dealTime); theArriveTime+=rand()%arriveTime+1; //首次到达时间 while(currentTime<closeTime) { ++currentTime; if(currentTimeOfDeal<currentTime)currentTimeOfDeal=currentTime; if(currentTimeOfDeal==currentTime)state=1; if(currentTime==theArriveTime) { arrive(); theArriveTime+=rand()%arriveTime+1;//到达事件 } if(1==state&&NULL!=fq.head) { if(fq.head->money>=0) { putMoney(); findAndDeal(); } else getMoney(); } } cout<<"客户逗留平均时间;"<<totalTime/counter<<endl; cout<<"银行当前余额:"<<total<<endl; break; } return 0; }
运行结果;