1、题目: 银行业务模拟(难度系数:1.3)运行环境VS问题描述客户业务分为两种。第一种是申请从银行得到一笔资金,即取款或借款。第二种是向银行投入一笔资金,即存款或还款。银行有两个服务窗口,相应地有两个队列。客户到达银行后先排第一个队。处理每个客户业务时,如果属于第一种,且申请额超出银行现存资金总额而得不到满足,则立刻排入第二个队等候,直至满足时才离开银行;否则业务处理完后立刻离开银行。每接待完一个第二种业务的客户,则顺序检查和处理(如果可能)第二个队列中的客户,对能满足的申请者予以满足,不能满足者重新排到第二个队列的队尾。注意,在此检查过程中,一旦银行资金总额少于或等于刚才第一个队列中最后一个客
2、户(第二种业务)被接待之前的数额,或者本次已将第二个队列检查或处理了一遍,就停止检查(因为此时已不可能还有能满足者)转而继续接待第一个队列的客户。任何时刻都只开一个窗口。假设检查不需要时间。营业时间结束时所有客户立即离开银行。 写一个上述银行业务的事件驱动模拟系统,通过模拟方法求出客户在银行内逗留的平均时间。基本要求利用动态存储结构实现模拟,即利用C语言的动态分配函数malloc和free。选做内容 自己实现动态数据类型。(已作) 1. 需求分析 计算来银行办理业务的用户平均逗留时间: 在运行终端控制台进行信息输入:输入信息包括(信息都为整数):1.银行拥有的款额 取值范围:0, 正无穷 2.
3、银行营业时间 取值范围:0, 1440 3.用户最大交易金额 取值范围:(0, 银行拥有款额 4.俩个用户到达时间的最大值取值范围:(0, 银行营业时间 5.用户最大交易时间 取值范围:(0, 银行营业时间 在运行终端控制台进行信息输出:1.每个到达用户的到达时间,编号,要处理的金额,处理时间2.事件表3.总用户数4.总逗留时间5.平均逗留时间 程序所能达到的功能;1.输出每个用户的到达时间,编号,要处理的金额,处理时间2.银行运营过程的全部事件(包括到达事件和离开事件)3.计算银行运营过程的用户数,总逗留时间,平均逗留时间 三组测试数据:1.正常情况:1.银行拥有的款额:100002.银行营
4、业时间: 6003.用户最大交易金额:20004.俩个用户到达时间的最大值:205.用户最大交易时间:15应输出:25.482.极端的情况:两个到达事件之间的间隔时间很短,而客户的交易时间很长1.银行拥有的款额:100002.银行营业时间: 6003.用户最大交易金额:20004.俩个用户到达时间的最大值:55.用户最大交易时间:100应输出:20.03.极端的情况:两个到达事件之间的间隔时间很长,而客户的交易时间很短1.银行拥有的款额:100002.银行营业时间: 6003.用户最大交易金额:20004.俩个用户到达时间的最大值:1005.用户最大交易时间:5应输出:88.38源代码如下:#
5、include #include #include #includetypedef int Status;#define OK 1#define ERROR -1/*#define MAXTIME 600/定义银行运作时间(单位:分钟 假设一分钟等于一秒)#define MAX_TIMEJIANGE 5/定义最大时间间隔#define MAX_TIMEJIAOYI 100/定义最大操作时间 */typedef struct kehu_event / 定义客户信息int handel_time; / 事件处理时间int money;/需要处理的钱数目(负数表示取钱,正数表示存钱)int No;/
6、客户的序号ElemType;typedef struct event/*定义事件类型*/int index;/*标志变量,1代表到达事件,其余代表离开事件*/int time;/*事件发生时间*/int No;/*触发该事件的客户序号*/event;typedef struct /*定义链表节点*/event data;struct LNode *next;LNode, *Link;typedef struct /*定义链表*/Link head, tail;int len;*LinkList;LinkList InitLink() /*初始化链表操作*/LinkList L = (LinkL
7、ist*)malloc(sizeof(LNode);if (L = NULL) return NULL;L-head = NULL;L-tail = NULL;L-len = 0;printf(链表初始化成功!);return L;Status ClearLink(LinkList L) /*链表的清空操作*/if (L = NULL) return ERROR;Link p = L-head;Link k = L-head-next;while (p != L-tail)free(p);p = k;if(k!=L-tail) k = k-next;free(p);L-head = NULL;
8、L-tail = NULL;L-len = 0;printf(链表已经清空!);return OK;Status DestoryLink(LinkList L) /*链表的销毁操作*/if (L = NULL) return ERROR;ClearLink(L);free(L);printf(链表销毁完毕!);return OK;Status InsertLink(LinkList L, event e) /*链表的尾部插入操作*/if (L = NULL) return ERROR;Link p = (Link)malloc(sizeof(LNode);if (p = NULL) retur
9、n ERROR;p-data = e;p-next = NULL;if (L-head = NULL) L-head = p;L-tail = p;L-len = 1;elseL-tail-next = p;L-tail = p;L-len+;/printf(节点插入成功!);return OK;Status LinkTraverse(LinkList L) /*链表的遍历操作*/if (L = NULL) return ERROR;Link p = L-head;printf(n遍历结果 :n);printf( 客户序号: 事件触发时间: 事件类型: );printf(n-);while (
10、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;return OK;typedef struct LQNode /*定义队列的节点*/ElemType data;struct LQNode *next;LQNode, *QueuePtr;typedef struct /*定义队列*/QueuePtr front;QueuePtr rear;int len;LQueue;LQueue
11、* InitQueue() /*构造一个空队列*/LQueue *Q = (LQueue *)malloc(sizeof(LQueue);if (Q = NULL) return ERROR;Q-front = NULL;Q-rear = NULL;Q-len = 0;return Q;Status EnQueue(LQueue *Q, ElemType e) /在队列的队尾插入eLQNode *p;p = (LQNode*)malloc(sizeof(LQNode);if (p = NULL) return ERROR;p-data = e;p-next = NULL;if ( NULL =
12、 Q-front) Q-front = p;Q-rear = p;Q-len = 1;elseQ-rear-next = p;Q-rear = p;Q-len+;return OK;Status DeQueue(LQueue *Q, ElemType *e) /是队列Q的队头出队并且返回到eLQNode *p;if (NULL = Q-front) return ERROR;p = Q-front;*e = p-data;Q-front = p-next;if (Q-rear = p) Q-rear = NULL;free(p);Q-len-;return OK;Status DestoryQ
13、ueue(LQueue *Q) /*队列的销毁操作*/if (Q = NULL)return ERROR;QueuePtr p=NULL, q=NULL;p = Q-front;while (p != Q-rear) q = p-next;myfree(p);p = q;free(Q-rear);return OK;Status InsertQueue(LQueue *Q, LQueue *E) /*将E队列插入到Q队列的前面,并将Q队列作为新的队列释放E*/if ( E = NULL | E-front = NULL)return ERROR;if (Q = NULL | Q-front =
14、 NULL | Q-rear = NULL) Q-front = E-front;Q-rear = E-rear;elseE-rear-next = Q-front;Q-front = E-front;return OK;/*-定义需要使用的全局变量-*/int total ; /*一天营业开始时银行拥有的款额为10000(元),并且默认取钱只能*/int total_time = 600;/*营业时间为600(分钟)*/int max_money;LQueue *handel_queue = NULL;/*定义第一个队列用于处理业务*/LQueue *wait_queue = NULL;/*
15、 定义第二个队列用于存储等候的客户*/LinkList event_link = NULL;/*定义一个事件表*/int nextTime = 0;/*定义一个变量作为下一个客户的随机到达时间*/int nexthandelTime = 0;/*定义一个变量作为正在排队的下一个客户处理时间*/int kehu_NO = 1;/*客户的服务序号*/ElemType *leave_kehu = NULL;/*定义一个办理完业务要离开的客户变量,用于记录*/ElemType *search_kehu = NULL;/*定义一个用来存储待处理业务的客户变量*/*-*/ElemType* mymallo
16、c( int max_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+;return e;Status myfree(ElemType *e) /*动态释放客户节点*/if (e = NULL)return ERROR;f
17、ree(e);return OK;/*Status suiji_kehu(ElemType *e,int max_timejiaoyi) /*随机生成客户信息mymalloc(e, max_timejiaoyi);return OK;*/ElemType* Arrial_event(int i, int max_timejiange, int max_timejiaoyi) /*用来处理新客户到达事件*/if (nextTime = i) printf(当前时间是:%dn, i);nextTime = nextTime + (rand() % max_timejiange) + 1;/随机生成
18、下一名客户到达时间,这里可以设置客户到达时间间隔的大小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 money) handel_time + i;tot
19、al = total + p-money;EnQueue(handel_queue, *p);else EnQueue(wait_queue, *p);else if (nexthandelTime = 0) /第一个进入操作的用户情况if (-(p-money) handel_time + i;total = total + p-money;EnQueue(handel_queue, *p);else EnQueue(wait_queue, *p);else EnQueue(handel_queue, *p);if (nexthandelTime = 0 ) /第一个进入操作的用户情况if
20、(-(p-money) handel_time + i;total = total + p-money;EnQueue(handel_queue, *p);else EnQueue(wait_queue, *p);printf(n 客户编号:%d 客户操作需要时间:%d 客户需要处理的钱:%d 银行余额:%dnnn, p-No, p-handel_time, p-money, total);return p;Status handel_event(int i) /*处理队列事件*/if (nexthandelTime = i) /*到达下一个客户操作时间时*/DeQueue(handel_qu
21、eue, leave_kehu);/将处理完的客户出队,并将客户信息存储在leave_kehu变量中int last_money = total - leave_kehu-money;/获取刚离开的客户操作前银行的钱数目Leave_event(leave_kehu, i);/将离开事件的用户信息存入事件列表中if (leave_kehu-money) 0) & wait_queue-front != NULL) /*如果刚刚离开的用户是存钱或者还钱,并且 等待队列 不为空*/int index = 0;/设置标记变量,用以标记等待队列已经查看的客户数目LQueue *e = InitQueue
22、();/创造出一个可以被满足需求的等待用户组成的队列int linshi_total = total;/设置一个临时金额存储空间while (linshi_total last_money & wait_queue-front != NULL) /如果当前银行拥有的款额比之前多,进入循环DeQueue(wait_queue, search_kehu);/将等待队列的队头用户出队if (-(search_kehu-money) money;else EnQueue(wait_queue, *search_kehu);index+;if (index = wait_queue-len)break;
23、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);EnQue
24、ue(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 & -
25、(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;Status Leave_event
26、(ElemType *e ,int i) /*用来处理客户离开事件*/event *p = (event*)malloc(sizeof(event);p-index = 0;p-No = e-No;p-time = i;InsertLink(event_link, *p);return OK;double average_StayTime(LinkList e,double final) /*通过事件列表来计算用户平均逗留时间*/double sum=0, a, b;int shumu=0;LNode *p = e-head;for (int i = 1; i len; i+) while(p
27、!=NULL) if (p-data.No = i) if (p-data.index = 1) a = p-data.time;shumu = shumu + 1;if (p-data.index = 0) b = p-data.time;p = p-next;p = e-head;if (b = -1.0) b = final;sum = sum + b - a;b = -1.0;printf(全部用户数: %d n总共消耗时间: %f n, shumu, sum);printf(客户平均逗留时间: %f 分, sum / shumu);return sum / shumu;int mai
28、n(void) leave_kehu = (ElemType*)malloc(sizeof(ElemType);search_kehu = (ElemType*)malloc(sizeof(ElemType);handel_queue = InitQueue();wait_queue = InitQueue();event_link = InitLink();srand(unsigned int)time(NULL);int MAXTIME, MAX_TIMEJIANGE, MAX_TIMEJIAOYI;printf(请输入银行的运营时间(单位:分钟):);scanf_s(%d, &MAXTI
29、ME);printf(请输入银行的运营金额(单位:元):);scanf_s(%d, &total);printf(请输入用户最大交易金额(单位:元):);scanf_s(%d, &max_money);printf(请输入俩个到达事件的最大时间间隔:(单位:分钟):);scanf_s(%d, &MAX_TIMEJIANGE);printf(请输入用户最大交易时间:(单位:分钟):);scanf_s(%d, &MAX_TIMEJIAOYI);/ElemType *newKehu = (ElemType*)malloc(sizeof(ElemType);for (int i = 0; i MAXTIME; i+)Arrial_event(i, MAX_TIMEJIANGE, MAX_TIMEJIAOYI);handel_event(i);Sleep(50);LinkTraverse(event_link);printf(n);average_StayTime(event_link, MAXTIME-1);DestoryQueue(handel_queue);DestoryQueue(wait_queue);system(pause);return 1;