SHH数据结构-【实训-银行业务的模拟系统 】

/*
* 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;
}

运行结果;

SHH数据结构-【实训-银行业务的模拟系统 】_第1张图片

你可能感兴趣的:(SHH数据结构-【实训-银行业务的模拟系统 】)