数据结构-银行业务模拟系统

本文介绍了一个基于事件驱动的银行业务模拟系统的设计与实现,涉及数据结构和算法的应用。系统通过模拟计算客户在银行逗留的平均时间,输出包括存款、取款等各种业务统计信息。在调试和测试过程中,强调了正确输入的重要性,并提供了不同测试场景的输出分析。文章还分享了作者在数据结构结合与理解方面的学习心得。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.需求分析
1.1输入的形式
输入的元素为整型类型;
输入的银行初始存款必须大于0;
输入的银行营业时间必须大于0且必须小于1440(一天);
输入的最大到达时间间隔必须大于0且必须小于银行营业时间;
输入的最小到达时间间隔必须大于0且必须小于最大到达时间间隔;
输入的最大处理时间必须大于0且必须小于银行营业时间;
输入的最小处理时间必须大于0且必须小于最大处理时间;
输入的交易额的最大上线必须大于0且必须小于银行初始存款且必须小于50000;
1.2输出的形式
输出的形式为以列表的形式输出事件处理序列;
并在列表输出完后输出需要存款的客户人数,需要取款的客户人数,成功办理存款的客户人数,成功办理取款的客户人数,存款成功办理率,取款成功办理率,客户逗留平均时间,银行当前余额等信息。
1.3程序功能
实现银行业务的事件驱动模拟系统,通过模拟方法求出客户在银行内逗留的平均时间。
1.4测试
测试数据由程序用户手动输入,此处对于正确输入和错误输入给出样例。
(1)错误的输入
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
(2)正确的输入
这里写图片描述
(3)对应的输出结果
这里写图片描述
2.概要设计
2.1数据类型
本设计中用到的数据结构ADT定义如下:

ADT Queue{
    数据对象:D={ ai | ai∈ElemSet, i=1,2,...,n,  n≥0 }
    数据关系:R1={ <ai-1, ai>|ai-1, ai∈D, i=2,...,n }
    基本操作:
void InitQueue(Queue &Q);
操作结果:构造空队列Q
CustNode *Queuefront(Queue &Q);
初始条件:队列Q存在
操作结果:返回队首元素
CustNode *Queuerear(Queue &Q);
初始条件:队列Q存在
操作结果:返回队尾元素
void EnQueue(Queue &Q,int e);
初始条件:队列Q存在
操作结果:插入元素e为Q的新的队尾元素。
void DeQueue(Queue &Q);
初始条件:队列Q存在
操作结果:删除Q的队头元素。
}ADT Queue

2.2主程序的流程
主程序先是让外部进行测试数据输入,待测试数据输入完后,执行银行业务模拟系统,产生需要取款的客户人数,成功办理存款的客户人数,成功办理取款的客户人数,存款成功办理率,取款成功办理率,客户逗留平均时间,银行当前余额等信息。

2.3程序模块说明
这里写图片描述

3.详细设计
3.1头文件声明
为了增强代码可读性,使用头文件来记录各类结构体的声明以及常用变量的定义

#ifndef _Bank_H_
#define _Bank_H_
#include <string>
using namespace std;

/*客户结点类型*/
struct CustNode{                        
    int num;                            //客户号  
    string Type;                        //到达或离开  
    int BeginTime;                      //到达时间  
    int EndTime;                        //离开时间  
    int Amount;                         //正数为存款,负数为取款  
    CustNode *next;                 //指针域  
};  

Struct Client{
Int arrivertime;                    //到达时间
Int durtime;                        //逗留时间
Int amount;                     //办理业务金额
Client *next;                       //指针域
};
Client pool[MaxNumber];

/*等待队列类型*/
struct Queue{                         
    CustNode *front;                    //队列头指针  
    CustNode *rear;                 //队列尾指针  
}Queue;  

/*常用变量定义*/
int BankAmount;                         //初始时银行现存资金总额  
int CloseTime;                      //营业结束时间  
int ClientArriveMaxTime;                //两个到达事件之间的间隔上限  
int ClientArriveMinTime;                //两个到达事件之间的间隔下限  
int DealMaxTime;                        //客户之间交易的时间上限  
int DealMinTime;                        //客户之间交易的时间下限  
int MaxAmount;                      //交易额上限  
int NeedIn=0;                           //需要存款的人数  
int NeedOut=0;                      //需要取款的人数  
int SuccessIn=0;                        //成功存款的人数  
int SuccessOut=0;                       //成功取款的人数  
int CurrentTime=0;                  //当前时间  
int BankAmountTime=0;               //客户逗留总时间  
int counter=0;                      //客户总数  
int number=1;                       //初始客户序列号  
bool state=1;                           //用于判断是否有窗口在处理  
int DealTime=0;                     //交易时间  
int MaxTime=0;                      //最大到达时间  
Queue Event;                            //事件队列  
Queue Q1;                           //队列一  
Queue Q2;                           //队列二 
#endif
3.2选做算法
3.2.1动态分配函数
/*出栈,将栈顶元素的下标返回*/
伪码表示:
Begin
Client *p<-栈顶指针
e的arrivetime<-栈顶元素的arrivertime
e的durtime<-栈顶元素的durtime
e的amount<-栈顶元素的amount
栈顶指针指向下一元素
End
代码表示:
void myMalloc(Stack &S,Client &e){
Client *p=S.top;
e.arrivetime=(*S.top).arrivetime;
e.durtime=(*S.top).durtime;
e.amount=(*S.top).amount;
p->next=p->next->next;
S.top++;
p=p->next;
}
3.2.2归还函数
/*把该分量入栈*/
伪码表示:
Begin
Client *p<-栈顶指针
栈底元素的arrivertimee<-e的arrivetime
栈底元素的durtime<-e的durtime
栈底元素的amount<-e的amount
栈底指针指向下一元素
End
代码表示:
void myFree(Stack &S,Client e){
Client *p=S.rear;
(*S.rear).arrivertime=e.arrivetime;
(*S.rear).durtime=e.durtime;
(*S.rear).amount=e.amount;
p->next=p->next->next;
S.rear++;
p=p->next;
}
3.3函数算法
3.3.1创建队列
/*初始化操作,建立一个空队列*/
伪码表示:
Begin 
分配存储空间给头结点和尾结点
IF头结点内存分配失败  
EXIT
头结点的指针域<-空 
End 
代码表示:
void InitQueue(Queue &Q){  
    Q.front=Q.rear=(CustNode*)malloc(sizeof(CustNode));  
    if(!(Q.front))  
         exit(1);  
    Q.front->next=0;  
 }  
3.3.2入队列
/*插入元素e为队列Q的新的队尾元素*/
伪码表示:
Begin
分配存储空间给结点p
结点p的金额置<-e
结点p的指针域<-空
IF队列<-空
Begin
头指针<-p
尾指针<-p
End
ELSE
Begin
头指针next域<-p
尾指针<-尾指针next域
End
End
代码表示:
void EnQueue(Queue &Q,int e){  
    CustNode* p=new CustNode;  
    p->Amount=e;  
    p->next=NULL; 
    if(Q.front==NULL){      
    //队列为空,初始化    
        Q.front=p;  
        Q.rear=p;  
    }  
    else{                     
    //队列不为空,插入结点p    
        Q.rear->next=p;  
        Q.rear=Q.rear->next;  
    }  
} 
3.3.3出队列
/*使p中的第一个元素出队列*/
伪码表示:
Begin
p<-头指针
IF p的next域<-空
Begin
头指针<-空
尾指针<-空
End
ELSE
头指针<-头指针的next域
DELETE p
End
代码表示:
void DeQueue(Queue &Q){  
    CustNode *p;  
    p=Q.front;  
    if(Q.front->next==NULL)     //队列只有一个元素  
        Q.front=Q.rear=NULL;  
    else                        //调整队列头指针 
        Q.front=Q.front->next;  
    delete p;  
}
3.3.4取队首
/*返回队首元素*/
伪码表示:
Begin   
Return 队首元素
End
代码表示:
CustNode *Queuefront(Queue &Q){  
    return Q.front;  
}

3.3.5取队尾  
/*返回队尾元素*/
伪码表示:
Begin
Return 队尾元素
End
代码表示:
CustNode *Queuerear(Queue &Q){  
    return Q.rear;  
}  
3.3.6处理客户到达事件
/*随机产生顾客,进入队列一产生到达事件 进入事件队列*/
伪码表示:
Begin
调用EnQueue(Q1,随机数)
Q1尾结点的BeginTime<-CurrentTime
Q1尾结点的num<-number
EnQueue(Event,尾结点的金额)
Event尾结点的BeginTime<-CurrentTime
Event尾结点的Type<-到达
Event尾结点的num<-number
number<-number+1
End
代码表示:
void ClientArrive(){  
    EnQueue(Q1,(rand()%(2*MaxAmount)-MaxAmount));   //随机产生顾客加入第一队列  
    Queuerear(Q1)->BeginTime=CurrentTime;               //当前时间为客户的到达时间  
    Queuerear(Q1)->num=number;                      //客户号为客户序列号  
    EnQueue(Event,(Queuerear(Q1)->Amount));             //将产生事件加入事件队列  
    Queuerear(Event)->BeginTime=CurrentTime;  
    Queuerear(Event)->Type="到达";  
    Queuerear(Event)->num=number;  
    number++;  
}  
3.3.7存款
/*对客户存款事件进行处理*/
伪码表示:
Begin
BankAmount<-BankAmount+Q1头结点的Amount
调用EnQueue(Event,Q1头结点的Amount)
Event尾结点的Type<-离开
Event尾结点的num<-Q1头结点的num
Event尾结点的EndTime<-Q1头结点的BeginTime+随机处理时间
counter<-counter+1
BankAmountTime<-BankAmountTime+Event尾结点的EndTime-Q1头结点的BeginTime
调用DeQueue(Q1)
DealTime<-Event尾结点的EndTime
state<-0
End
代码表示:
void InAmount(){
    BankAmount+=Queuefront
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值