银行业务模拟(C语言)

银行业务模拟
【问题描述】
假设某银行有 4 个窗口对外接待客户,银行开门时间 9:00AM,关门时间 5:00PM,
从早晨银行开门起不断有客户进入银行。由于每个窗口在某个时刻只能接待一个客户,因此
在客户人数众多时需要在每个窗口前顺次排队,对于刚进入银行的客户(建议:客户进入时
间使用随机函数产生),如果某个窗口的业务员正空闲,则可上前办理业务;反之,若 4 个
窗口均有窗户所占,他便会排在人数最少的队伍后面。【基本要求】
(1)编制一个程序以模拟银行的这种业务活动,并计算一天中每个窗口对外接待的客
户数量;
(2)客户到达时间随机产生,一天客户的人数上限设定为 100 人;银行业务员处理时
间随机产生,平均处理时间 10 分钟;
(3)每次发生状态更新,则进行输出,格式可以表示为:时间,事件,当前各窗口前
的客户数;
(4)具备良好的人机交互界面。【实现提示】
(1)客户产生编号及到达的时间函数单独封装;
(2)银行业务员处理的时间函数单独封装;
(3)每个窗口使用一个队列进行模拟;
(4)客户选择窗口的功能单独封装;
(5)状态输出函数单独封装。
(最好写成项目形式)

img

不知道为什么一味依赖gpt实现思路,这种提问ai理解能力不行,这是我实现的code,你可以在继续改动:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define WINDOW_NUM 4  
#define OPEN_TIME 9   
#define CLOSE_TIME 17 

typedef struct Customer {
    int id;        
    int arrive;    
    int process;   
} Customer;

typedef struct Window {
    int id;                 
    int process_time_left;  
    int customer_num;       
    Customer *customer;     
} Window;

typedef struct Node {
    Customer *customer;  
    struct Node *next;   
} Node;

typedef struct Queue {
    Node *front;  
    Node *rear;   
    int length;   
} Queue;

int get_random(int n) {
    return rand() % n;
}

void init_queue(Queue *queue) {
    queue->front = queue->rear = NULL;
    queue->length = 0;
}

int is_empty(Queue *queue) {
    return queue->length == 0;
}

void enqueue(Queue *queue, Customer *customer) {
    Node *node = (Node *)malloc(sizeof(Node));
    node->customer = customer;
    node->next = NULL;

    if (is_empty(queue)) {
        queue->front = queue->rear = node;
    } else {
        queue->rear->next = node;
        queue->rear = node;
    }

    queue->length++;
}

void dequeue(Queue *queue) {
    if (is_empty(queue)) {
        return;
    }

    Node *temp = queue->front;
    queue->front = queue->front->next;
    queue->length--;

    free(temp);
}

Customer *peek(Queue *queue) {
    if (is_empty(queue)) {
        return NULL;
    }

    return queue->front->customer;
}

void init_windows(Window *windows, int n) {
    for (int i = 0; i < n; i++) {
        windows[i].id = i + 1;
        windows[i].process_time_left = 0;
        windows[i].customer_num = 0;
        windows[i].customer = NULL;
    }
}

Window *get_shortest_queue_window(Window *windows, int n) {
    Window *shortest_window = &windows[0];

    for (int i = 1; i < n; i++) {
        if (windows[i].customer_num < shortest_window->customer_num) {
            shortest_window = &windows[i];
        }
    }

    return shortest_window;
}

void print_windows(Window *windows, int n, int current_time) {
    printf("时间:%02d:%02d:%02d\n ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
    printf("当前状态:");

    for (int i = 0; i < n; i++) {
        printf("窗口 %d: %d号顾客 ", windows[i].id, windows[i].customer_num);
        if (windows[i].customer) {
            printf("(正在排的顾客到了 %d号, 还有%d 分钟剩余时间)", windows[i].customer->id, windows[i].process_time_left);
        } else {
            printf("窗口空闲\n");
        }

        if (i < n - 1) {
            printf(", ");
        }
    }

    printf("\n");
}

void simulate(int customer_num, int avg_process_time) {
    srand((unsigned)time(NULL));  

    Queue queue;
    init_queue(&queue);

    Window windows[WINDOW_NUM];
    init_windows(windows, WINDOW_NUM);

    int current_time = OPEN_TIME * 3600;
    int customer_id = 1;

    while (current_time < CLOSE_TIME * 3600 && customer_id <= customer_num) {

        if (get_random(4) == 0) {
            Customer *customer = (Customer *)malloc(sizeof(Customer));
            customer->id = customer_id++;
            customer->arrive = current_time;
            customer->process = get_random(avg_process_time * 2) + 1;

            enqueue(&queue, customer);
            printf("%02d:%02d:%02d, ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
            printf("顾客 %d 到达, 需要 %d 分钟.\n", customer->id, customer->process);
        }

        for (int i = 0; i < WINDOW_NUM; i++) {
            Window *window = &windows[i];

            if (window->customer) {
                window->process_time_left--;

                if (window->process_time_left == 0) {
                    printf("%02d:%02d:%02d, ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
                    printf("顾客 %d 在窗口%d 结束.\n", window->customer->id, window->id);

                    free(window->customer);
                    window->customer = NULL;
                }
            }
        }

        for (int i = 0; i < WINDOW_NUM; i++) {
            Window *window = &windows[i];

            if (!window->customer && !is_empty(&queue)) {
                window->customer = peek(&queue);
                window->process_time_left = window->customer->process;
                dequeue(&queue);

                window->customer_num++;
                printf("%02d:%02d:%02d, ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
                printf("顾客 %d 去窗口 %d.\n", window->customer->id, window->id);
            }
        }

        for (int i = 0; i < WINDOW_NUM; i++) {
            Window *window = &windows[i];

            if (window->customer) {
                window->customer_num = 1;
            } else {
                window->customer_num = 0;
            }

            window->customer_num += queue.length;
        }

        print_windows(windows, WINDOW_NUM, current_time);

        current_time++;
    }

    while (!is_empty(&queue)) {
        Customer *customer = peek(&queue);
        dequeue(&queue);
        free(customer);
    }
}

int main() {
    simulate(100, 10); 
    return 0;
}


根据需求,增加界面显示:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define WINDOW_NUM 4
#define OPEN_TIME 9
#define CLOSE_TIME 17

typedef struct Customer {
    int id;
    int arrive;
    int process;
} Customer;

typedef struct Window {
    int id;
    int process_time_left;
    int customer_num;
    Customer *customer;
} Window;

typedef struct Node {
    Customer *customer;
    struct Node *next;
} Node;

typedef struct Queue {
    Node *front;
    Node *rear;
    int length;
} Queue;

int get_random(int n) {
    return rand() % n;
}

void init_queue(Queue *queue) {
    queue->front = queue->rear = NULL;
    queue->length = 0;
}

int is_empty(Queue *queue) {
    return queue->length == 0;
}

void enqueue(Queue *queue, Customer *customer) {
    Node *node = (Node *)malloc(sizeof(Node));
    node->customer = customer;
    node->next = NULL;
    if (is_empty(queue)) {
        queue->front = queue->rear = node;
    } else {
        queue->rear->next = node;
        queue->rear = node;
    }
    queue->length++;
}

void dequeue(Queue *queue) {
    if (is_empty(queue)) {
        return;
    }
    Node *temp = queue->front;
    queue->front = queue->front->next;
    queue->length--;
    free(temp);
}

Customer *peek(Queue *queue) {
    if (is_empty(queue)) {
        return NULL;
    }
    return queue->front->customer;
}

void init_windows(Window *windows, int n) {
    for (int i = 0; i < n; i++) {
        windows[i].id = i + 1;
        windows[i].process_time_left = 0;
        windows[i].customer_num = 0;
        windows[i].customer = NULL;
    }
}

Window *get_shortest_queue_window(Window *windows, int n) {
    Window *shortest_window = &windows[0];
    for (int i = 1; i < n; i++) {
        if (windows[i].customer_num < shortest_window->customer_num) {
            shortest_window = &windows[i];
        }
    }
    return shortest_window;
}

void print_windows(Window *windows, int n, int current_time) {
    printf("时间:%02d:%02d:%02d\n ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
    printf("当前状态:");
    for (int i = 0; i < n; i++) {
        printf("窗口 %d: %d号顾客 ", windows[i].id, windows[i].customer_num);
        if (windows[i].customer) {
            printf("(正在排的顾客到了 %d号, 还有%d 分钟剩余时间)", windows[i].customer->id, windows[i].process_time_left);
        } else {
            printf("窗口空闲\n");
        }
        if (i < n - 1) {
            printf(", ");
        }
    }
    printf("\n");
}

void simulate(int customer_num, int avg_process_time) {
    srand((unsigned)time(NULL));
    Queue queue;
    init_queue(&queue);
    Window windows[WINDOW_NUM];
    init_windows(windows, WINDOW_NUM);
    int current_time = OPEN_TIME * 3600;
    int customer_id = 1;
    while (current_time < CLOSE_TIME * 3600 && customer_id <= customer_num) {
        if (get_random(4) == 0) {
            Customer *customer = (Customer *)malloc(sizeof(Customer));
            customer->id = customer_id++;
            customer->arrive = current_time;
            customer->process = get_random(avg_process_time * 2) + 1;
            enqueue(&queue, customer);
            printf("%02d:%02d:%02d, ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
            printf("顾客 %d 到达, 需要 %d 分钟.\n", customer->id, customer->process);
        }
        for (int i = 0; i < WINDOW_NUM; i++) {
            Window *window = &windows[i];
            if (window->customer) {
                window->process_time_left--;
                if (window->process_time_left == 0) {
                    printf("%02d:%02d:%02d, ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
                    printf("顾客 %d 在窗口%d 结束.\n", window->customer->id, window->id);
                    free(window->customer);
                    window->customer = NULL;
                }
            }
        }
        for (int i = 0; i < WINDOW_NUM; i++) {
            Window *window = &windows[i];
            if (!window->customer && !is_empty(&queue)) {
                window->customer = peek(&queue);
                window->process_time_left = window->customer->process;
                dequeue(&queue);
                window->customer_num++;
                printf("%02d:%02d:%02d, ", current_time / 3600, (current_time % 3600) / 60, current_time % 60);
                printf("顾客 %d 去窗口 %d.\n", window->customer->id, window->id);
            }
        }
        for (int i = 0; i < WINDOW_NUM; i++) {
            Window *window = &windows[i];
            if (window->customer) {
                window->customer_num = 1;
            } else {
                window->customer_num = 0;
            }
            window->customer_num += queue.length;
        }
        print_windows(windows, WINDOW_NUM, current_time);
        current_time++;
    }
    while (!is_empty(&queue)) {
        Customer *customer = peek(&queue);
        dequeue(&queue);
        free(customer);
    }
}

int main() {
    printf("请输入要进行的操作:\n");
    printf("1. 运行模拟程序\n");
    printf("2. 关闭程序\n");
    printf("3. 关于本程序\n");
    int choice;
    scanf("%d", &choice);
    while (choice != 2) {
        switch (choice) {
            case 1:
                simulate(100, 10);
                break;
            case 3:
                printf("这是银行排队模拟程序。\n");
                break;
            default:
                printf("无效操作!\n");
                break;
        }
        printf("\n请输入要进行的操作:\n");
        printf("1. 运行模拟程序\n");
        printf("2. 关闭程序\n");
        printf("3. 关于本程序\n");
        scanf("%d", &choice);
    }
    return 0;
}


以下是一个基于C语言实现银行业务模拟的示例代码,包含了随机产生客户到达时间和窗口处理时间、使用队列模拟每个窗口的等待队列、以及状态输出等功能。代码中使用了头文件queue.h和time.h,需要将其包含在源代码文件中。


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <queue.h>

#define NUM_WINDOWS 4
#define MAX_CUSTOMERS 100

// 客户结构体
typedef struct customer {
    int id; // 客户编号
    int arrival_time; // 到达时间
    int service_time; // 处理时间
} Customer;

// 窗口结构体
typedef struct window {
    int id; // 窗口编号
    int serving; // 是否正在为客户服务
    int remaining_time; // 剩余服务时间
    queue waiting_queue; // 等待队列
} Window;

int main() {
    srand(time(NULL)); // 初始化随机数种子

    Customer customer_list[MAX_CUSTOMERS]; // 客户列表
    Window window_list[NUM_WINDOWS]; // 窗口列表

    // 初始化窗口
    for (int i = 0; i < NUM_WINDOWS; i++) {
        window_list[i].id = i + 1;
        window_list[i].serving = 0;
        window_list[i].remaining_time = 0;
        init_queue(&window_list[i].waiting_queue);
    }

    int num_customers = 0; // 已经到达的客户数量
    int current_time = 9 * 60; // 当前时间(从早上9点开始)

    printf("时间\t事件\t窗口1\t窗口2\t窗口3\t窗口4\n");

    // 不断循环直到银行关门
    while (current_time < 17 * 60) {
        // 随机产生客户到达时间和处理时间
        if (num_customers < MAX_CUSTOMERS && rand() % 5 == 0) {
            customer_list[num_customers].id = num_customers + 1;
            customer_list[num_customers].arrival_time = current_time;
            customer_list[num_customers].service_time = (rand() % 6 + 5) * 10;
            num_customers++;

            printf("%02d:%02d\t客户%d到达\t", current_time / 60, current_time % 60, num_customers);
            for (int i = 0; i < NUM_WINDOWS; i++) {
                printf("%d\t", queue_size(&window_list[i].waiting_queue));
            }
            printf("\n");
        }

        // 处理窗口服务状态
        for (int i = 0; i < NUM_WINDOWS; i++) {
            if (window_list[i].serving == 1) { // 如果正在为客户服务
                window_list[i].remaining_time--; // 剩余服务时间减一

                if (window_list[i].remaining_time == 0) { // 如果已经完成服务
                    window_list[i].serving = 0; // 取消服务状态

                    if (!is_empty(&window_list[i].waiting_queue)) { // 如果等待队列中还有其他客户
                        Customer next_customer = *(Customer *)queue_front(&window_list[i].waiting_queue);
                        dequeue(&window_list[i].waiting_queue); // 取出等待队列中的下一个客户
                        window_list[i].serving = 1; // 开始为此客户服务
                        window_list[i].remaining_time = next_customer.service_time; // 记录剩余服务时间

                        printf("%02d:%02d\t客户%d开始在窗口%d受理\t", current_time / 60, current_time % 60, next_customer.id, i + 1);
                        for (int j = 0; j < NUM_WINDOWS; j++) {
                            printf("%d\t", queue_size(&window_list[j].waiting_queue));
                        }
                        printf("\n");
                    }
                }
            } else { // 如果没有正在为客户服务
                if (!is_empty(&window_list[i].waiting_queue)) { // 如果等待队列中还有其他客户
                    Customer next_customer = *(Customer *)queue_front(&window_list[i].waiting_queue);
                    dequeue(&window_list[i].waiting_queue); // 取出等待队列中的下一个客户
window_list[i].serving = 1; // 开始为此客户服务
window_list[i].remaining_time = next_customer.service_time; // 记录剩余服务时间

                printf("%02d:%02d\t客户%d开始在窗口%d受理\t", current_time / 60, current_time % 60, next_customer.id, i + 1);
                for (int j = 0; j < NUM_WINDOWS; j++) {
                    printf("%d\t", queue_size(&window_list[j].waiting_queue));
                }
                printf("\n");
            }
        }
    }

    current_time++; // 当前时间加一分钟
}

// 统计每个窗口处理的客户数量
int num_served[NUM_WINDOWS] = {0};
for (int i = 0; i < NUM_WINDOWS; i++) {
    while (!is_empty(&window_list[i].waiting_queue)) {
        Customer customer = *(Customer *)queue_front(&window_list[i].waiting_queue);
        dequeue(&window_list[i].waiting_queue);
        num_served[i]++;
    }
    if (window_list[i].serving == 1) {
        num_served[i]++;
    }
}

printf("\n每个窗口服务情况:\n");
for (int i = 0; i < NUM_WINDOWS; i++) {
    printf("窗口%d服务的客户数:%d\n", i+1, num_served[i]);
}

return 0;
}


此程序使用了两个自定义结构体,分别表示客户和窗口。其中,客户结构体包含了客户编号、到达时间和处理时间三个属性;窗口结构体包含了窗口编号、服务状态(是否正在为客户服务)、剩余服务时间和等待队列四个属性。程序随机产生客户到达时间和处理时间,并使用队列模拟每个窗口的等待队列。在处理窗口服务状态时,如果有窗口为空闲,则立即为刚到达银行的客户服务;否则,将该客户插入人数最少的队伍末尾。一旦一个窗口完成服务,就会去检查自己的等待队列中是否还有其他客户需要服务。程序不断循环直到银行关门,最后统计每个窗口处理的客户数量。

此程序还实现了状态输出功能,以方便观察模拟过程中各窗口前的客户数量。同时,也有良好的人机交互界面。

以下功能可以参考下

#include <iostream>
#include <string>
#include <windows.h>
#include "CustomClass.h" 

using namespace std;

//------------------------------------------最主要的功能函数-------------------------------------------------- 
//是否准备开始下一轮模拟 
void startAnotherSimulate()
{
    int select = 0;
    
    cout << "Ready to leave and get another data?If you ready to leave please inputed the “1 ”:";

    while (select != 1)
    {
        cin >> select;
        
        if (select != 1)
        {
            cout << "input error,please input again(you need to inputed the  “1 ”!!!)" << endl;
        }
    } 
}

//打印所有窗口的每个业务的办理次数 
/*
    参数一:Bank类的名为窗口的对象数组
    参数二:该对象数组的长度 
*/
void showAllWindow(Bank *window, int window_length) 
{
    int i = 0;
    int count = 0;
     
    for (i = 0; i < window_length; i++)
    {
        cout << "窗口:" << ++count << "的存款办理次数:" << window[i].getSaveMoneyNum() << " " << "取款办理次数:" << window[i].getGetMoneyNum() << " " << "挂失办理次数:" << window[i].getReportLossOfNum() << " " << "贷款办理次数:" << window[i].getRefundNum() << " " << endl;
        cout << "该窗口总计接纳人数:" << (window[i].getSaveMoneyNum() + window[i].getGetMoneyNum() + window[i].getReportLossOfNum() + window[i].getRefundNum()) << endl;
        cout << endl;
    }
}

//冒泡排序,用来对客户数组按升序排序
/*
    参数一:Client类的对象数组
    参数二:对象数组的长度 
*/
void bubbleSortForClientArray(Client *client, int client_length)
{
    int j;
    int exchange;//交换位置记录 
    int bound;//遍历区间 
    Client temp_client;//临时存储
    
    exchange = client_length - 1;//交换位置初始化,第一趟冒泡排序区间0~client_length-1 
    
    while (exchange != 0)
    {
        bound = exchange;
        exchange = 0;
        
        for (j = 0; j < bound; j++)//接下来每趟冒牌排序区间是0~bound
        {
            if (client[j].getClientArriveTime() > client[j+1].getClientArriveTime())
            {
                temp_client = client[j];
                client[j] = client[j+1];
                client[j+1] = temp_client;    
            }                
            
            exchange = j;
        }    
    } 
} 

//统计一天客户在银行的平均逗留时间
/*
    参数一:Bank类的对象数组
    参数二:对象数组的长度 
*/
void statisticData(Bank *window, int window_length)
{
    int i = 0;//用来控制循环 
    
    int client_all_stay_time = 0;//客户总的逗留时间 
    int all_client_num = 0;//今日总到客量 
    double client_average_time;//客户今日平均逗留时间 
    
    for (i = 0; i < window_length; i++)
    {
        //顾客逗留总时间为:所有窗口的客户逗留时间累加 
        client_all_stay_time += window[i].getClientStayBankTime();
        
        //今日总到客量为:所有窗口的所有业务办理量的累加
        all_client_num += (window[i].getGetMoneyNum() + window[i].getSaveMoneyNum() + window[i].getReportLossOfNum() + window[i].getRefundNum());
    }
    
    //输出窗口的信息:
    showAllWindow(window,window_length);//统计
    
    client_average_time = ((double)client_all_stay_time / (double)all_client_num);//客户一天平均逗留时间 = 客户今日总逗留时间 / 今日到客总量 
    cout << "今日客户平均逗留时间:" << client_average_time << endl; 
}

//-------------------------------------------------------------------------下列方法是辅助startWorking方法的子方法-----------------------------------------------------------------
//找到此时服务时间超过了银行营业时间的窗口,并将它关闭 
/*
    参数一:Bank类的名为window的对象数组
    参数二:对象数组的长度 
    参数三:银行关门时间 
*/
void setWindowStatusByBankEndTime(Bank *window, int window_length, int bank_end_time)
{
    int i = 0;
    for    (i = 0; i< window_length; i++)
    {
        if (window[i].getBusinessStartTime() >= bank_end_time)
        {
            window[i].setWindowsEmpty(false);    
        } 
    }
} 
                    
//找到业务办理结束时间最小的窗口 
/*
    参数一:Bank类的名为window的对象数组
    参数二:对象数组的长度 
*/
int getMinTimeByWindow(Bank *window, int window_length)
{
    int i;
    int index;
    
    int min = window[0].getbusinessEndTime();
    
    for (i = 0; i < window_length; i++)
    {
        if (min >= window[i].getbusinessEndTime())
        {
            min = window[i].getbusinessEndTime();
            index = i;//记录结束时间最小的窗口下标 
        }
    }
    
    return index;//放回窗口数组中办理时间最短的那个窗口的下标 
} 

//-------------------------------------------------------------------------下列方法是模拟银行的核心方法!!!--------------------------------------------------------------------

//窗口开始工作 
/*
    参数一,客户队链
    参数二,窗口数组
    参数三,窗口长度 
*/
void startWorking(int open_time, int closed_time)//运用变量模拟线程 
{
    //-----------------------------队链以及窗口建立-------------------------  
    const int client_array_length = 100;//顾客数组最大长度 
    const int window_length = 4;//窗口数量 
    Client client[client_array_length];//创建顾客数组 
    bubbleSortForClientArray(client, client_array_length);//对客户数组冒泡排序做入队准备 
    LinkedQueue client_queue;
    client_queue.joinQueue(client, client_array_length, open_time, closed_time);//建队 
    //用银行类建立4个窗口 
    Bank windows[window_length] = {Bank(open_time, closed_time), Bank(open_time, closed_time), Bank(open_time, closed_time), Bank(open_time, closed_time)};
    //-----------------------------队链以及窗口建立------------------------- 
    
    int i;//用来控制遍历空窗口的循环 
    int j;//用来控制遍历业务办理时间最小窗口的循环 
    
    int index_for_min = 0;//记录结束时间最小的窗口下标
    int bank_end_time = 0;//记录银行结束营业时间 
    
    int now_temp_all_time_min = 0;//记录当前办理时间最短的那个窗口的结束办理时间 
    
    bank_end_time = windows[0].getBankClosedTime() * 60;//将银行结束营业时间存储并转化为分钟表达。
        
    if(client_queue.empty() == true)
    {
        //如果等待队列一开始就为空的话那就退出 
    } else
        {
            while (client_queue.empty() != true && now_temp_all_time_min <= bank_end_time)//只要队列还有元素或者此时办理时间最小的窗口的总时间没超银行营业结束时间 
            {
                //如果窗口都不为空 
                   if(!windows[0].getWindowsEmpty() && !windows[1].getWindowsEmpty() 
                       && !windows[2].getWindowsEmpty() && !windows[3].getWindowsEmpty())
                {
                     index_for_min = getMinTimeByWindow(windows, window_length);//调用找最小下标的找到业务办理结束时间最小的窗口
                     
                    windows[index_for_min].setWindowsEmpty(true);//时间最小的窗口设置为没人状态 
                    windows[index_for_min].setBusinessStartTime(windows[index_for_min].getbusinessEndTime());//将最快办理完毕的窗口的下一个业务开始办理时间设置为它上一个业务办理的结束时间 
                    now_temp_all_time_min = windows[index_for_min].getbusinessEndTime();//将此时办理时间最短的窗口的时间设置为总时间
                    
                    setWindowStatusByBankEndTime(windows, window_length, bank_end_time);//找到此时服务时间超过了银行营业时间的窗口,并将它关闭,意味着它不再接受客人 
                    
                } else//否则执行业务办理 
                    {
                        //执行出队操作
                        Client client = client_queue.deleteQueue();//用一个临时对象来存储当前出队对象 
                        
                        //遍历找到当前空的窗口 
                           for (i = 0; i < window_length; i++)
                           {
                            
                              if (windows[i].getWindowsEmpty() == true)//找到当前空的窗口并输出打印 
                              {
                                  cout << "当前到来顾客在第 " << i+1 << " 窗口办理业务" << endl;
                                  client.showClientInfor();//打印当前办理业务的客户的票的信息
                                cout << endl;
                                cout << endl;  
                                  
                                  //如果此时到达该窗口的用户的时间远大于窗口上一个业务办理完毕的时间(也就是该窗口业务下一个业务开始时间) 
                                  //那么就将该业务下一个业务开始时间 = 下一个顾客到来的时间 
                                   if (client.getClientArriveTime() > windows[i].getBusinessStartTime())
                                  {
                                      windows[i].setBusinessStartTime(client.getClientArriveTime());    
                                }
                                  
                                windows[i].setWindowsEmpty(false);//将该窗口设置为有人状态 

                                switch (client.getClientBusinessName())//运用当前出队对象的得到办理的业务方法来得到当前出队用户在该窗口办理的业务种类以及逗留时间和当前窗口该业务办理结束时间。 
                                 {
                                     case 0:
                                             //设置当前窗口办理结束时间为,窗口上一个人办理完毕的时间 + 当前到来顾客需要办理的时间 
                                             windows[i].setbusinessEndTime(windows[i].getBusinessStartTime() + client.getClientBusinessNameTime());
                                             //用户逗留时间 = 用户离开的时间(窗口服务当前客户结束时间)- 用户到达的时间
                                             windows[i].setClientStayBankTime((windows[i].getbusinessEndTime() - client.getClientArriveTime()));//当前窗口顾客逗留时间累加

                                             windows[i].setSaveMoneyNum();//当前窗口的存款办理次数+1

                                               break;
    
                                      case 1:
                                                //设置当前窗口办理结束时间为,窗口上一个人办理完毕的时间 + 当前到来顾客需要办理的时间 
                                             windows[i].setbusinessEndTime(windows[i].getBusinessStartTime() + client.getClientBusinessNameTime());
                                             //用户逗留时间 = 用户离开的时间(窗口服务当前客户结束时间)- 用户到达的时间
                                             windows[i].setClientStayBankTime((windows[i].getbusinessEndTime() - client.getClientArriveTime()));//当前窗口顾客逗留时间累加
                                             
                                            windows[i].setGetMoneyNum();//当前窗口的取款办理次数+1 

                                             break;
                                             
                                      case 2:
                                               //设置当前窗口办理结束时间为,窗口上一个人办理完毕的时间 + 当前到来顾客需要办理的时间 
                                             windows[i].setbusinessEndTime(windows[i].getBusinessStartTime() + client.getClientBusinessNameTime());
                                             //用户逗留时间 = 用户离开的时间(窗口服务当前客户结束时间)- 用户到达的时间
                                             windows[i].setClientStayBankTime((windows[i].getbusinessEndTime() - client.getClientArriveTime()));//当前窗口顾客逗留时间累加
                                             
                                             windows[i].setReportLossOfNum();//当前窗口的挂失办理次数+1 
                                             break;
                                             
                                       case 3:
                                            //设置当前窗口办理结束时间为,窗口上一个人办理完毕的时间 + 当前到来顾客需要办理的时间 
                                             windows[i].setbusinessEndTime(windows[i].getBusinessStartTime() + client.getClientBusinessNameTime());
                                             //用户逗留时间 = 用户离开的时间(窗口服务当前客户结束时间)- 用户到达的时间
                                             windows[i].setClientStayBankTime((windows[i].getbusinessEndTime() - client.getClientArriveTime()));//当前窗口顾客逗留时间累加
                                             
                                             windows[i].setRefundNum();//当前窗口的贷款办理次数+1 
                                             break;
                                             
                                       default:
                                               cout << "error!" << endl;
                                               break; 
                                   }
                            }
                            
                           }
                    }
                    
                Sleep(500);//每执行一次循环就睡眠0.5秒模拟顾客缓缓到来 
                
            }
            
                cout << "Today's data generation is complete :" << endl;
                statisticData(windows, window_length);
                startAnotherSimulate();
        }
}


你这个功能挺多的,在这里不太可能得到完整功能的代码,你可以参考下面的思路来实现。
1.定义客户结构体,包括客户编号、到达时间和处理时间等信息。
2.定义窗口结构体,包括队列、窗口状态、当前正在处理的客户等信息。
3.编写随机函数模块,生成随机的客户到达时间和银行业务员处理时间。
4.编写队列模拟模块,使用队列来模拟每个窗口前的客户。
5.编写客户选择窗口模块,选择最短的队列长度的窗口,并将该客户加入这个窗口的队列中。
6.编写状态输出模块,输出当前的状态信息。
7.在主程序中循环模拟一天的银行业务流程,同时调用状态输出模块输出当前的状态。

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/263271
  • 除此之外, 这篇博客: C语言实现八大排序算法详解及其性能之间的中的 这里需要对堆有一定的了解,堆就是一个比较特殊的完全二叉树,在最大堆里,每个节点的值都大于其左右两个孩子节点的值。这就是最大堆。反之就是最小堆。拿最大堆举例子,每次堆顶的元素值,不就是当前数列的最大吗?这不就成选择排序里的简单排序了吗?找完之后,将他和完全二叉树里最后一个结点的值进行交换,然后做一个自顶向下的自我调整,将他再次调整成一个完全二叉堆。第二次取最大的树,这时我们需要将上一次找到的结点屏蔽掉,不然会陷入一个死循环。无数次找完之后,再按层序的思想将二叉树里的数据遍历到一个数组当中,这时的数组为一个有序的数组。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 算法思想