(C++)链队列实现银行业务模拟

文章描述了一个银行的业务模型,涉及客户取款和存款,以及两个服务窗口对应的队列管理。文章要求编写一个事件驱动的模拟程序,计算客户在银行内的平均等待时间。
摘要由CSDN通过智能技术生成

任务

银行客户业务分为两种:第一种是申请从银行得到一笔资金,即取款或借款;第二种是向银行投入一笔资金,即存款或还款。

银行有两个服务窗口,相应地有两个队列。客户到达银行后先排第一个队,处理每个客户业务时,如果属于第一种,且申请额超出银行现存资金总额而得不到满足,则立刻排入第二个队等候直至满足时才离开银行;否则业务处理完后立刻离开银行,每接待完一个第二种业务的客户,则顺序检查和处理(如果可能)第二个队列中的客户,对能满足的申请者予以满足,不能满足者重新排到第二个队列的队尾。注意,在此检查过程中,一旦银行资金总额少于或等于刚才第一个队列中最后一个客户(第二种业务)被接待之前的数额,或者本次已将第二个队列 检查或处理了一遍,就停止检查(因为此时已不可能还有能满足者),转而继续接待第一个队列的客户。任何时刻都只开一个窗口。假设检查不需要时间,营业时间结束时所有客户立即离开银行。
写一个上述银行业务的事件驱动模拟系统,通过模拟方法求出客户在银行内逗留的平均时间。


输入格式

第一行输入四个数 N、total、close_time、average_time,分别表示来银行的总人数、银行开始营业时拥有的款额、今天预计的营业时长和客户交易时长,之后的 N 行每行输入两个数 a、b,第一个数 a 为客户办理的款额,用负值和正值分别表示第一类和第二类业务。第二个数 b 为客户来到银行的时间。

输出格式

前 N 行输出分别对应每个客户的等候时长
第 N+1 行输出为客户等候平均时长,结果去尾法保留整数即可

输入样例

4 10000 600 10
-2000 0
-11000 10
-10000 30
2000 50

输出样例

第1个顾客的等待时间为0
第2个顾客的等待时间为590
第3个顾客的等待时间为30
第4个顾客的等待时间为0
4个顾客的平均等待时间为155

样例解释

开始时银行有存款 10000 元,顾客交易时长 10
1号顾客0时刻到达银行,于 10 时办理完手续离开,此时银行有款额8000元;
2号顾客10时刻到达银行,此时银行内存款不足,进入队列 2;
3号顾客30时刻到达银行,此时银行内存款不足,进入队列 2;
4号顾客50时刻到达银行,于60时办理完手续离开,此时银行有款额10000元。
这时扫描队列2,队列2中第一个顾客2号顾客的要求仍然不满足,2 号顾客出队再入队;此时队列 2 中第一个顾客3号客户满足要求,因此3号顾客于60时刻开始办理手续,于70时刻办理完毕离开银行,等待时间为60-30=30,此时银行有余款 0 元。
然后直到银行营业时间 600时刻之前2号客户都没有离开银行,等待时间为600-10=590。

源代码

队列相关操作

#include<iostream>
using namespace std;
typedef struct QueueList{
    int num; //顾客序号
    struct QueueList* next;
}Queue;

Queue* EnQueue(Queue** Q,int n){//将顾客进队
    Queue *p=(Queue*)malloc(sizeof(Queue));
    if(!p){
        printf("申请空间失败");
        return NULL;
    }
    p->num=n;
    if(!*Q){
        *Q=p;
        (*Q)->next=NULL;
    }
    else{
        Queue* q=*Q;
        while(q->next)
            q=q->next;
        q->next=p;
        p->next=NULL;
    }
    return *Q;
}

int DeQueue(Queue** Q){//将队首顾客出队
    if(!*Q)
        return -1;
    int i;
    Queue *p=*Q;
    i=p->num;
    *Q=(*Q)->next;
    free(p);
    return i;
}

模拟过程

int main(){
    int n,i,arrive[50]={0},status[50],Time=0,wait[50]={0},waittotal=0,waitaverage=0,closetime=0,avetime=0,Money=0,money[50]={0},moneytemp=0;
    //n为顾客人数,arrive数组记录每个顾客来到银行的时间,status数组记录每个顾客的状态,-1为未来银行,0为正在等待,1为已离开
    //Time表示当前时间,wait数组记录每个顾客等待的时间,waittotal是所有顾客等待的总时间,waitaverage是顾客等待的平均时间,closetime是银行关门时间,avetime是每笔交易的平均时间
	//Money为银行一开始的款额,money数组记录每个顾客的交易金额,正数为存钱,负数为取钱,moneytemp用来记录第一个队列最后一个客户(第二种业务)接待前银行的剩余款额
	cout<<"请依次输入顾客总人数、银行开始营业时拥有的款额、今天预计的营业时长和客户交易时长"<<endl;
	cin>>n>>Money>>closetime>>avetime;
    Queue* Q=NULL;
    cout<<"请依次输入每个顾客要交易的款额(用负值和正值分别表示第一类和第二类业务)和客户来到银行的时间"<<endl;
    for(i=0;i<n;i++){
        cin>>money[i]>>arrive[i];
        status[i]=-1;
    }
    for(i=0;i<n;i++){
        if (arrive[i]>=closetime-avetime) {//在关门前完成不了交易相当于一直等到关门
            status[i]=0;
            break;
        }
        else {
        	if(Time<arrive[i])
			    Time=arrive[i];//重置当前时间
            if(money[i]<0){//第一种业务:取钱
                if(-money[i]<=Money){//银行有足够余额
                    Money+=money[i];
                    wait[i]=Time-arrive[i];
                    status[i]=1;
                    Time+=avetime;//重置当前时间
                    moneytemp=Money;
                    if(Time>=closetime)
                        loop:break;
                }
                else{//银行没有足够余额,进入第二条队等待
                    status[i]=0;
                    EnQueue(&Q,i);
                }
            }
            else{//第二种业务
                Money+=money[i];
                wait[i]=Time-arrive[i];
                status[i]=1;
                Time+=avetime;//重置当前时间
                int status2[50]={0};//用来标记第二条队的顾客是否被检查到,没检查是0,检查到是1
                while (Money>moneytemp){
                	Money+=money[i];
                wait[i]=Time-arrive[i];
                status[i]=1;
                Time+=avetime;//重置当前时间
                int status2[50]={0};//用来标记第二条队的顾客是否被检查到,没检查是0,检查到是1
                while (Money>moneytemp){
                	int k=DeQueue(&Q);
                	if(k==-1) break;
                	else if(!status2[k]){
					if(-money[k]<=Money){
                        Money+=money[k];
                        wait[k]=Time-arrive[k];
                        status[k]=1;
                        Time+=avetime;//重置当前时间
                        moneytemp=Money;
                        if(Time>=closetime)
                            goto loop;//跳出while循环和for循环
					}
					else{
                        status2[i]=1;
                        EnQueue(&Q,i);//不满足就重新入队
                    }
                }
            }
        }
    }
}
    for ( i = 0; i < n; i++){
    	if(!status[i])
           wait[i]=closetime-arrive[i];
    	cout<<"第"<<i+1<<"个顾客的等待时间为"<<wait[i]<<endl;
    }
    for ( i = 0; i < n; i++)
        waittotal+=wait[i];
    waitaverage=waittotal/n;
    cout<<n<<"个顾客的平均等待时间为"<<waitaverage<<endl;
    return 0;
}

#include<stdio.h> <br>#include<string.h> <br>double qu(double dbYe) <br>{ <br>double dbQu=0.0; <br>int nA=0,nB=0; <br>while(nB==0) <br>{ <br>printf("请输入取款金额:"); <br>scanf("%lf",&dbQu); <br>if(dbYe<dbQu) <br>{ <br>printf("余额不足,重新输入取款金额按1,退出请按0"); <br>scanf("%d",&nA); <br>printf("\n"); <br>if(nA==1) <br>{ <br>continue; <br>}else <br>{ <br>break; <br>} <br>}else <br>{ <br>dbYe=dbYe-dbQu; <br>printf("正在准备现金,请稍等……\n"); <br>printf("操作成功,请取走现金\n"); <br>break; <br>} <br>} <br>return dbYe; <br>} <br>double cun(double dbCun) <br>{ <br>printf("请输入存款金额:"); <br>scanf("%lf",&dbCun); <br>printf("正在存入现金请稍等\n"); <br>printf("操作成功\n"); <br>return dbCun; <br>} <br>double cha(double dbYe) <br>{ <br>char cA=0; <br>printf("您帐户的余额为%.2lf元\n",dbYe); <br>return dbYe; <br>} <br><br><br><br>void main() <br>{ <br>int nA=1,nB=1,nXz=0; <br>double dbYe=100000,dbCun=0.0; <br>char ID[]={"thinkbank"}; <br>char PW[20]={"tb"}; <br>char sID[20]={"0"}; <br>char sPW[20]={"0"}; <br>while(nA==1) <br>{ <br>printf("========================\n"); <br>printf("==欢迎使用自助银行系统==\n"); <br>printf("========================\n"); <br>printf("\n\n"); <br>printf("请输入您的帐号:\n"); <br>scanf("%s",&sID); <br>printf("请输入您的密码:\n"); <br>scanf("%s",&sPW); <br>if(strcmp(ID,sID) != 0 && strcmp(PW,sPW) != 0) <br>{ <br>printf("您输入的帐号或密码错误,请重新输入\n"); <br>continue; <br>} <br>nB=1; <br>while(nB==1) <br>{ <br>printf("可执行的操作\n"); <br>printf("1.取款\n"); <br>printf("2.存款\n"); <br>printf("3.查询余额\n"); <br>printf("4.修改密码\n"); <br>printf("5.退出\n"); <br>printf("请选择您要进行的操作:"); <br>scanf("%d",&nXz); <br>switch(nXz) <br>{ <br>case 1: <br>{ <br>dbYe=qu(dbYe); <br>break; <br>} <br>case 2: <br>{ <br>dbYe=dbYe+cun(dbCun); <br>break; <br>} <br>case 3: <br>{ <br>cha(dbYe); <br>break; <br>} <br>case 4: <br>{ <br><br>break; <br>} <br>case 5: <br>{ <br>nB=2; <br>break; <br>} <br>default: <br>{ <br><br>printf("您的输入有误,请重新选择所要进行的操作\n"); <br>break; <br>} <br>} <br>} <br>} <br>}<br>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里澄江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值