1、东北大学信息科学与工程学院数据结构课程设计报告题目 银行业务模拟课题组长 侯永跃课题组成员 林浩成 李博然 韩硕专业名称 计算机科学与技术班级 计1307指导教师 杨雷2015 年 1月课程设计任务书题目:银行业务模拟问题描述:银行有N个窗口对外接待客户。从早晨银行营业开始到晚间营业终止不断有客户办理业务。银行门口设有取号机,分为一般业务和特殊业务,设每个一般业务不超过5分钟,每个特殊业务不超过15分钟。客户在等候区内等候叫号。设计要求: 设计银行客户业务的模拟程序。(1)采用有序链表、队列等数据结构。(2)分类统计一天内客户在银行逗留的平均时间和人数。(3)若特殊业务窗口空闲,可办理一般业务
2、。(4)可以随机或人工输入客户到达银行的时间。 (5)其它完善性功能。指导教师签字:年月日目录1 课题概述41.1 课题任务41.2 课题原理41.3 相关知识52 需求分析52.1 课题调研52.2 用户需求分析63 方案设计63.1 总体功能设计63.2 数据结构设计93.3 函数原型设计103.4 主算法设计113.5 用户界面设计144 方案实现154.1 开发环境与工具154.2 程序设计关键技术164.3 个人设计实现(按组员分工)4.3.1 侯永跃设计实现16 4.3.2 李博然设计实现23 4.3.3 林浩成设计实现28 4.3.4 韩硕设计实现325 测试与调试355.1 个
3、人测试355.1.1 侯永跃测试35 5.2 组装与系统测试385.3 系统运行416 课题总结436.1 课题评价436.2 团队协作446.3 下一步工作446.4 个人设计小结(按组员分工)446.4.1 侯永跃设计小结44 6.4.2 李博然设计小结45 6.4.3 林浩成设计小结45 6.4.4 韩硕设计小结467 附录A 课题任务分工46A-1 课题程序设计分工46A-2 课题报告分工49 附录B 课题设计文档(光盘)49B-1课程设计报告(电子版)49B-2源程序代码(*.H,*.CPP)49B-3工程与可执行文件)49 B-4屏幕演示录像文件(可选)49 附录C 用户操作手册(
4、可选)49C.1 运行环境说明49C.2 操作说明491 课题概述1.1课题任务 银行业务模拟【问题描述】银行有N个窗口对外接待客户。从早晨银行营业开始到晚间营业终止不断有客户办理业务。银行门口设有取号机,分为一般业务和特殊业务,设每个一般业务不超过5分钟,每个特殊业务不超过15分钟。客户在等候区内等候叫号。【设计要求】设计银行客户业务的模拟程序。(1)采用有序链表、队列等数据结构。(2)分类统计一天内客户在银行逗留的平均时间和人数。(3)若特殊业务窗口空闲,可办理一般业务。(4)可以随机或人工输入客户到达银行的时间。(5)其它完善性功能。 通过本实验理解并掌握数据结构及其应用,巩固程序设计基
5、础知识,初步学习软件工程、可视化程序设计的知识,提高编程水平和分析问题、解决问题的能力,增强学习能力和合作能力。1.2 课题原理本程序主要采用链表、队列等数据结构,链表定义为有序链表,实现了事件之间的联系。本设计关键在于对事件的处理,将银行业务模拟分为客户到达银行办理业务事件、办理业务结束离开银行事件。客户到达银行、离开银行等事件的信息都存入链表中,对链表可以进行插入、写入文件等操作。另外我们将银行办理业务的不同窗口定义为不同的数组,客户在各自窗口前排队成为队列,银行有N个窗口,各自为不同的数组,在各个窗口前,每个队列的队头是正在窗口办理业务的客户,队头出队的时刻就是客户离开银行的时刻,也即客
6、户离开事件的发生,此时可以利用对有序表的处理引入下一名客户到达事件。程序主要通过模拟银行一天从早到晚客户到达、客户入队、客户离开的事件来完成程序的功能。通过合理的随机模拟,模拟出一天内银行的总客户数、客户累计逗留时间、客户平均逗留的时间、一般业务与特殊业务的办理次数等。这些信息写入到文件中,便于查找和统计。1.3 相关知识(1) 对有序链表的构造和处理。(2) 对离散事件的模拟,理解动态规划的有关概念。(3) 对队列中元素的插入,删除等操作。(4) 对文件的操作。(5) 一定的MFC有关知识。2 需求分析2.1 课题调研 调研结果: 在实际生活中,人们经常去银行办理业务,如何能够正确有效地安排
7、客户的顺序成为关键。所以程序应注重高效性。 另外,银行大多有办理不同种业务的窗口。银行开设的窗口有一般业务窗口和特殊业务窗口,特殊业务窗口往往较少。 客户办理业务时的情况分为两种,一种是客户到来时恰好有合适的办理业务的窗口,另一种是客户不全在办理业务(即等待)。银行办理一般业务与特殊业务的客户数量肯定会相差很多,一般业务往往比特殊业务的客户数多。因此,如果特殊窗口无人办理业务,可以让办理一般业务的客户去特殊窗口办理。另外,客户叫号后几乎没有在等待过程中离开的,因此程序中忽略客户叫号后离开不办理业务的情形。2.2 用户需求分析用户分为两类:银行客户和银行职员。程序的用户操作端分为客户端和银行端,
8、客户端由银行客户操作,银行客户通过客户端叫号,等待或者去窗口办理业务(程序中的客户到达时间由此决定,这些操作通过随机模拟实现);银行端由银行窗口的职员操作,主要办理业务、设置业务窗口数(程序中的客户离开时间由此决定,这些操作也通过模拟实现)。银行端还可以对当日的业务人数以及办理的时间等信息进行统计和分析,将其与之前模拟的信息比较,得出有关的业务情况。 3 方案设计3.1 总体功能设计经过讨论,我们决定程序总体可以实现以下功能:(1) 能够模拟银行一天内的客户办理业务的事件。(2) 统计银行业务的客户数、办理业务的时间等信息。(3) 可以查询以往模拟的信息。(4) 可以实现数据的输入来更改其中的
9、信息。(5) 当前窗口的人员分布情况动态显示。(6) 界面要求达到有合理的提示,根据提示可以完成相关功能要求。具体分析:程序主要通过模拟银行一天从早到晚客户到达事件、离开的时刻、逗留时间,可通过保存、查询、打印以上信息,来完成程序的功能。通过合理的随机模拟,模拟出一天内银行的总客户数、客户累计逗留时间、客户平均逗留的时间、一般业务与特殊业务的办理次数,一般业务与特殊业务的办理人数和逗留时间。这些信息写入到文件中,用户可以再次查询、打印、统计。并且,在应用MFC之后,这些有关数据可以在界面中得以直观显示。以下是可视化UML图: 基于MFC可视化的UML类图以下是银行业务模拟的相应流程图: 3.2
10、 数据结构设计 程序的数据结构包括链表、队列和有关的数组等。 事件链表记录客户的事件,窗口队列记录客户排队的信息,记录信息链表将所有的客户信息按照不同的类别保存到链表中。银行窗口q5是一个数组,保存窗口队列头结点。/事件结构体typedef struct Event_Node int OccurTime; /事件发生时刻 int NType; /事件类型,-1表示到达,0-4代表在那个窗口离开 int type; /0-4 Event_Node *next; /指向下一个Event_Node, *Event; /事件类型,有序链表LinkList的数据元素类型/队列结构体typedef str
11、uct Queue_Node int ArrivalTime; /到达时刻 int Duration; /办业务持续时间 int type; /客户的真实业务类型0-4 Queue_Node *next; /指向下一个结点Queue_Node, *Queue, LinkList_Node, *LinkList; /队列的数据元素类型/客户信息记录链表typedef struct EndLinkList_node int OrderNum; /编号 int ArrivalHour; /到达小时数 int ArrivalMin; /到达分钟数 int DepartureHour; /离开小时数 i
12、nt DepartureMin; /离开分钟数 EndLinkList_node *next;EndLinkList_Node,*EndLinkList;3.3 函数原型设计事件结点类成员函数原型:OrderInsertEv(Event_Node *e); /按序插入事件表中EmptyEve(); /判断事件表是否为空DeletefirEve(); /删除事件表的第一个结点队列结点类成员函数原型:OutQueue(); /出队列函数EnQueue(Queue_Node *p); /入队列函数EmptyQue(); /判断队列是否为空Queue_Node* Getfirnode(); /获取队列
13、第一个结点QueueLength(); /队列的长度信息记录结点类成员函数原型:Record_Linklist(); 事件类成员函数原型:Simulate();CustomArrived(); /客户到达事件函数CustomerDeparture(); /处理客户离开事件,en.NType0Bank_Simulation(); /银行业务模拟函数OpenForDay(); /准备函数InitAll(); /初始化函数Random(int &durtime, int &intertime, int &type); /随机函数Minimum(); /查找最小队列RecordLinkList(int
14、 i, int j); /记录客户的信息链表,分别记录不同窗口的信息ChangeForm(); /客户信息转化函数Output(); /输出模拟完的结果Print_former(); /输出以前信息菜单函数Print_current(); /输出当前信息菜单函数StoreFile(); /永久保存到文件中StoreTotempfile(); /保存到临时文件中3.4 主算法设计/初始化函数void InitAll() TotalTime = 0; /总时间 CustomerNum = 0; /总人数 spetotaltime = 0; /办理特殊业务的总逗留时间 comtotaltime =
15、0; /办理一般业务的总逗留时间 EV = new Event_Node; /事件表创建头结点 /初始化三种链表以及队列 InitQueue(qi); /i = 0,1,2,3,4 aj = new LinkList_Node; bk = new EndLinkList_Node; /k =0,1,2,3,4,5 /客户到达事件函数void CustomArrived() int durtime; /逗留时间 int intertime; /下一个客户到达的时间 int type; /窗口类型 int t; /记录下一个客户到达的时刻 Event e; /事件变量 Event temp = n
16、ew Event_Node; Queue s = new Queue_Node; /队列结点变量 int i; /最小的队列的下标 Random(durtime, intertime, type); /产生随机值:逗留时间,下一个客户到达时间,以及下一个客户的业务类型 t = en-OccurTime + intertime; /下一个客户到达的具体时间 if(t ArrivalTime = en-OccurTime; /当前事件的到达时间 s-Duration = durtime; /当前事件的逗留时间 s-next = NULL; s-type = en-type; if(en-type
17、= 0) i = 0; spe+; spetotaltime += durtime; EnQueue(qi, s); /如果当前结点的业务类型是特殊业务,则入到第0个队列里 else i = Minimum(); /否则查找最小的队列 com+; comtotaltime += durtime; EnQueue(qi, s); /将其插入到队列中 if(QueueLength(qi) = 1) temp-NType = i; temp-OccurTime = s-ArrivalTime + s-Duration; temp-type = en-type; temp-next = NULL; O
18、rderInsert(temp); /处理客户离开事件,en.NType -1void CustomerDeparture()int i = en-NType, j = en-type;Queue p = new Queue_Node;Event e = new Event_Node;RecordLinkList(aj, qi); /记录客户事件 outQueue(qi);if(!(QueueEmpty(qi) /判断事件表是否为空p = GetHead(qi);e-OccurTime = p-ArrivalTime + p-Duration;e-NType = i;e-type = p-ty
19、pe;OrderInsert(e);/银行业务模拟函数void Bank_Simulation()OpenForDay();int i = 6;while(!EmptyEventList()en = EV-next; DelFirstNode();if(en-NType = -1) /判断事件类型CustomArrived();elseCustomerDeparture();ChangeForm(); StoreTofile(); /将模拟的信息保存到文件中Output();3.5 用户界面设计概要设计原理:本实验基于MFC的界面的设计,是通过创建对话框类来实现,在窗口的控件中定义一些事件对象
20、,来调用其成员函数模拟,信息查询需要创建一个子窗口,在此窗口中,需要使用MFC中的文件类来打开文件,然后将相应的模拟信息输出。最后回到主窗口,退出或者模拟。此件需要用到按钮控件,编辑框控件,还有显示框控件等控件。4 方案实现4.1 开发环境与工具开发环境:windows 7开发工具:VC+6.04.2 程序设计关键技术 根据我们的理解,本实验主要有以下要点: (一) 如何对客户发生的事件处理。我们采用了将这些事件记录在有序的链表当中,将客户的到达,离开这些事件定义为结点,然后插入事件表中,构建事件表,然后对每一个事件进行处理,要么到达,要么入队列,要么离开。通过这种方式,我们不需要在产生客户事
21、件的时候去不停的判断窗口的状态。这是一个动态的过程。 (二) 如何产生随机的事件,比如随机时间,随机逗留时间,随机窗口类型。我们在随机函数中设置了一个sleep()函数,用来暂停一段时间,让函数产生的随机数更准确,不重复。我们也设置了每两个客户之间的时间间隔。这些数据设置对产生的随机数有很大的影响。比如,如果我们将暂停时间设置得非常小,那么产生的随机数重复的概率就会大大的增加,以此我们不停的模拟,然后设置,还有是两个客户之间的时间间隔也会影响窗口的客户数量,我们模拟然后设置后发现将此间隔时间设置为10-15分钟之间时,客户在每个窗口的数量会比较均匀。4.3 个人设计实现(按组员分工)4.3.3
22、侯永跃程序设计实现main() menu(); return 0;/输出当前信息函数void Print_current() int i; system(cls); system(color 8a); couttttt输出本次模拟的客户信息nnnendl; cout0.输出本次模拟的特殊窗口的客户信息endl; cout1.输出本次模拟的1号一般窗口的客户信息endl; cout2.输出本次模拟的2号一般窗口的客户信息endl; cout3.输出本次模拟的3号一般窗口的客户信息endl; cout4.输出本次模拟的4号一般窗口的客户信息endl; cout5.输出本次模拟的一整天的客户信息(客
23、户编号,客户到达时间,客户离开时间)nnni; while(1) if(i = 0 & i = 5) switch(i) case 0: Print_file(0); break; case 1: Print_file(1); break; case 2: Print_file(2); break; case 3: Print_file(3); break; case 4: Print_file(4); break; case 5: Print_file(5); break; break; else cout你的输入有问题,请重新输入!i; /输出信息菜单void Print_fun() in
24、t i; /选择 system(cls); system(color 9a); couttttt模拟的信息输出nnnn; couti; while(1) if(i = 1) /Print_former(); break; else if(i = 2) Print_current(); break; else coutttt你的选择有误,请重新输入!i; /打印文件信息void Print_file(int num) /打印文件信息,num代表文件的编号 FILE *fp; char ch; switch(num) case 0: fp = fopen(0本次模拟特殊窗口客户信息文件.txt,
25、r); break; case 1: fp = fopen(1本次模拟1号一般窗口客户信息文件.txt, r); break; case 2: fp = fopen(2本次模拟2号一般窗口客户信息文件.txt, r); break; case 3: fp = fopen(3本次模拟3号一般窗口客户信息文件.txt, r); break; case 4: fp = fopen(4本次模拟4号一般窗口客户信息文件.txt, r); break; case 5: fp = fopen(5本次模拟客户所有信息文件.txt, r); break; default: coutnnttt你的的输入有问题,请
26、重新输入!; fclose(fp); return ; if(fp = NULL) couttttt文件内容为空!endl; fclose(fp); return ; while(!feof(fp) /cin.sync(); fscanf(fp, %c, &ch); putchar(ch); fclose(fp);/菜单显示void menu() system(cls); system(color 9a); int i; coutttt*银行模拟系统*nnnnn; coutttt1.银行模拟tt2.打印信息i; switch(i) case 1: Bank_Simulation(); /模拟函
27、数 Sleep(3000); menu(); break; case 2: Print_fun(); Sleep(3000); menu(); break; default: cout您的输入有误!请重新输入:endl; Sleep(1000); menu(); break; /输出模拟完的结果void Output() system(cls); system(color aa); couttttt模拟的结果显示如下:nnn; cout*银行这一天7:00 - 19:00,客户逗留时间和是:TotalTime分钟endl;cout*这一天总的客户人数是:CustomerNumendl;cout
28、*平均每个客户逗留的时间是:(double)TotalTime / CustomerNum分钟endl;cout*办理特殊业务的总人数是:speendl;coutzong shijian:spetotaltimeendl;cout*办理普通业务的总人数是:comendlzongshinjian: comtotaltimeendlnext = NULL; /初始化三种链表以及队列 for(int i = 0; i 5; i+) InitQueue(qi); for(int j = 0; j next = NULL; for(int k = 0; k next = NULL; /创建事件结点Eve
29、nt CreateEvNode(int OccurTime, int NType, int type)/创建结点 Event e; e = new Event_Node; if(!e) return 0; e-next=NULL; e-OccurTime = OccurTime; e-NType = NType; e-type = type; return e;/初始化队列void InitQueue(Queue &q) q = new Queue_Node; q-next = NULL; q-ArrivalTime = 0; q-Duration = 0;4.3.2 李博然程序设计实现/读取
30、文件信息int readFilec(har * filename) int x = 0, y = 0; char lineszLINE; int lines = 0; FILE * f = fopen(filename, r); while(!feof(f) memset(line, 0, szLINE); fgets(line, szLINE - 1, f); sscanf(line, %d|%d, &x, &y); /这里取到了x和y,用SetWindowText输出即可 printf(%d # t = %dn, x, y); lines +; /end while fclose(f);
31、return lines;/end readFile:void CustomArrived(); /客户到达事件函数void Random(int &durtime, int &intertime, int &type); /随机函数void StoreTofile(); /保存到文件中/客户到达事件函数void CustomArrived() int durtime; /逗留时间 int intertime; /下一个客户到达的时间 int type; /窗口类型 int t; /记录下一个客户到达的时刻 Event e; /事件变量 Event temp = new Event_Node;
32、 Queue s = new Queue_Node; /队列结点变量 int i; /最小的队列的下标 Random(durtime, intertime, type); /产生随机值:逗留时间,下一个客户到达时间,以及下一个客户的业务类型 t = en-OccurTime + intertime; /下一个客户到达的具体时间 if(t ArrivalTime = en-OccurTime; /当前事件的到达时间 s-Duration = durtime; /当前事件的逗留时间 s-next = NULL; s-type = en-type; if(en-type = 0) i = 0; spe+; spetotaltime += durtime; EnQueue(qi, s); /如果当前结点的业务类型是特殊业务,则入到第0个队列里 else i = Minimum(); /否则查找最小的队列 com+; comtotaltime += durtime;