莫思身外无穷事
且尽生前有限杯
我们先来看一下项目需求:
【场景】
在日常生活中,我们普遍接触到窗口服务系统,如到银行柜台办理业务、景区现场购买门票等。当需要办理业务的顾客数超过窗口数量时,我们需遵循排队等待原则。
【需求】
请设计并实现一个银行窗口排队管理系统,模拟用户排队、办理业务结束后离队等过程。具体要求如下:
1、窗口配置及状态管理
2、窗口应有编号、业务类型、排队队列、工作人员编号(唯一)等属性;
3、窗口数量无限制;
4、业务类型、窗口配置数据由系统启动时通过配置文件读取;
5、窗口可以动态增加或删除,但存在排队的窗口不能被删除;
6、窗口业务状态支持暂停,暂停时该窗口不再接受顾客排队;
7、暂停的窗口支持业务恢复;
8、窗口配置数据需持久化存储。
关于银行管理系统老铁们最先想到的是什么数据结构呢?--应该就是队列吧(先进先出)
今天我将带领大家一起完成银行管理系统
银行管理的登入界面
代码可以烂,但是逼格一定要高
就先从做个登入界面开始吧,其实是套用之前 C语言 的
void menu2()
{
int input = 0, count = 0, i = 0;
char mima[20] = "123";//登入的密码
char shuru[20] = { 0 };
system("color F4");
printf("\t\t\t **************************************\n");
printf("\t\t\t | *欢迎光临东方银行* |\n");
printf("\t\t\t | *管理员: 东方* |\n");
printf("\t\t\t ------------------------------------\n");
printf("请输入管理员密码:\n");
while ((count = _getch()) != '\r')
{
if (count == '\b')
{
i--;
printf("\b \b");
}
else
{
shuru[i++] = count;
printf("*");
}
}
shuru[i++] = '\0';
if (strcmp(mima, shuru) == 0)
{
printf("\n密码正确,您已进入系统!\n");
}
else
{
printf("\n密码错误,请重新输入!\n");
exit(0); //输入错误,直接退出
}
system("pause");
system("cls");
}
如果你的密码不小心输入错误了,就会直接退出系统
基本框架的实现
老铁们可以看到我创建了 6 个文件,应该应该很好理解吧,用户类、窗口类、银行操作类以及队列的模板
我这里就将简单的框架展示出来:
用户类:
//user.h
#include<string>
#include"Queue.h"
using std::string;
class user
{
public:
string name; //用户编号
int arrive_time; //用户到达时间
bool identity; //顾客身份
int cost_time; //办理业务花费时间
int leave_time; //离开时间
int wait_time; //等待时间
int enter_window; //代表取钱窗口
};
窗口类:
//Window.h
class Window
{
public:
int num; //窗口号
int wait_user; //窗口等待人数
};
队列模板:
模板是个好东西 ~ 无脑往里带
//Queue.h
template <typename T>
class QueueNode
{
public:
T data;
QueueNode* prev;
QueueNode* next;
};
template <typename T>
class Queue
{
public:
Queue();
~Queue();
bool empty() const
{
return _size == 0;
}
int size() const
{
return _size;
}
void push(const T&x);
void pop();
T front();
T back();
private:
QueueNode<T>* head;
QueueNode<T>* tail;
int _size;
};
template <typename T>
Queue<T>::Queue()
{
head = new QueueNode <T>;
tail = new QueueNode <T>;
head->prev = NULL;
head->next = tail;
tail->prev = head;
tail->next = NULL;
_size = 0;
}
template <typename T>
Queue<T>::~Queue()
{
while (_size != 0)
{
QueueNode<T>* t;
t = head->next;
head->next = head->next->next;
head->next->prev = head;
delete t;
_size--;
}
}
template <typename T>
void Queue<T>::push(const T& x)
{
QueueNode<T>* t = new QueueNode<T>;
t->data = x;
t->prev = tail->prev;
t->next = tail;
tail->prev->next = t;
tail->prev = t;
_size++;
}
template <typename T>
void Queue<T>::pop()
{
if (_size)
{
QueueNode<T>* t;
t = head->next;
head->next = head->next->next;
head->next->prev = head;
delete t;
_size--;
}
}
template <typename T>
T Queue<T>::front()
{
return head->next->data;
}
template <typename T>
T Queue<T>::back()
{
return tail->prev->data;
}
接下来就是银行操作类了
//BankCard.h
#include <iostream>
#include"user.h"
#include"Window .h"
#include<algorithm>
#include<time.h>
#include<cstdio>
#include<conio.h>
#include <fstream>
#include<windows.h>
using namespace std;
class BankCard
{
public:
//初始化
void BankCard_init();
//构造函数
BankCard()
{
BankCard_init();
}
//手册
void handbook();
//查看窗口人数
void show();
//计算离开时间和更新等待时间
void count_time(user& p);
//检查队列中是否有离开的人
void check_leave(int time);
//进入银行取票
void enter_bank(user& p);
//打印表单
void charts(int n);
//用户入队列
void manual();
//菜单-选项
void menu();
//新增窗口
void addition();
//删减窗口
void reduction();
//窗口暂停
void suspend();
//存档文件
int archived();
//办理的业务类型
int vbusiness();
};
怎么感觉 C++ 代码的风格跟 C 语言一样,算了,接下来我将讲解银行操作中的功能函数实现:
(如果有人说为什么不写析构函数,因为模板那里会自动掉析构)
银行操作类的环境搭建
Queue<user>* window_normal = new Queue<user>[3]; //队列数组用于窗口的增删
static int sum = 3; //静态变量表示存钱窗口数
Queue<user> window_VIP; //取钱队列
Queue<user> leave; //记录每个人离开队列的时间,用于判断顾客是否离开
user Person[1000]; //实例化顾客对象
int time_now; //记录当前时间
int person_num; //记录顾客人数
先说明一下,我们银行系统的时间的移动是根据最后一个进入的客户进行调整的
其他变量我们后面讲到了,在细讲器作用
比较函数:用于 sort 作用就是快速筛选出排队人数最少的窗口,来优化我们客户入队列的效率问题
//选择出最佳窗口
bool comp(Window x, Window y)
{
//若窗口等待人数相同时按窗口号大小排序
if (x.wait_user == y.wait_user)
{
return x.num < y.num;
}
//否则按窗口等待人数排序
return x.wait_user < y.wait_user;
}
时间转换函数
在我们系统中时间都是转换成分钟进行运算以及比较的,而在打印的时候才需要进行转换
void transform(int num)
{
cout << 9 + num / 60 << ":" << num % 60;
}·
银行操作类的构造函数
void BankCard::BankCard_init()
{
time_now = 0;
person_num = 0;
for (int i = 0; i < sum; i++)
{
while (!window_normal[i].empty())
{
window_normal[i].pop();
}
}
while (!window_VIP.empty())
{
window_VIP.pop();
}
while (!leave.empty())
{
leave.pop();
}
}
就像以入新家一样要把之前残留的东西都清理一下 ~
银行操作类的菜单页面
别的先不说,先来看看我们的大纲:
void BankCard::menu()
{
while (true)
{
printf("\t\t\t*****************************************************\n");
printf("\t\t\t*---------------------------------------------------*\n");
printf("\t\t\t* 欢迎光临东方银行 *\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t********************系统功能菜单*********************\n");
printf("\t\t\t---------------------- --------------------------\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 1、录入客户信息 * 2、查看窗口信息 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 3、查询排队情况 * 4、退出排队系统 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 5、使用系统手册 * 6、存档系统文件 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 7、窗口状态新增 * 8、窗口状态删减 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 9、窗口业务暂停 * 0、窗口业务恢复 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t---------------------- --------------------------\n");
cout << "请输入你将要执行的操作>:" << endl;
int input;
cin >> input;
system("cls");
switch (input)
{
case 1:
{
manual();
system("pause");
system("cls");
break;
};
case 2:
{
show();
system("pause");
system("cls");
menu();
break;
};
case 3:
{
charts(person_num);
system("pause");
system("cls");
menu();
break;
};
case 4:
{
cout << "*-----------------------*" << endl;
cout << "<<><>欢迎使用本系统<><>>*" << endl;
cout << "*-----------------------*" << endl;
exit(0);
};
case 5:
{
handbook();
system("pause");
system("cls");
break;
}
case 6:
{
archived();
system("pause");
system("cls");
break;
}
case 7:
{
addition();
system("pause");
system("cls");
break;
}
case 8:
{
reduction();
system("pause");
system("cls");
break;
}
case 9:
{
suspend();
system("pause");
system("cls");
break;
}
}
}
}
银行操作类的录入用户
int BankCard::vbusiness()
{
cout << "*-----------------------*" << endl;
cout << "<<><>0.办理存钱窗口<><>>*" << endl;
cout << "<<><>1.办理取钱窗口<><>>*" << endl;
cout << "*-----------------------*" << endl;
int input;
cout << "请输入你想办理的业务>:" << endl;
cin >> input;
if (input == 0) return 0;
if (input == 1) return 1;
}
void BankCard::manual()
{
while (1)
{
double t;
cout << "*-----------------------*" << endl;
cout << "《=======姓名=======》"; cin >> Person[person_num].name;
cout << "《=======到达时间=======》"; cin >> t;
double temp = int(t - 9.0) * 60 + (t - int(t)) * 100;
if (temp < time_now)
{
cout << "请按时间先后顺序输入" << endl;
system("pause");
system("cls");
continue;
}
Person[person_num].arrive_time = temp;
int r = rand() % 30 + 1;//生成0到30的随机数
Person[person_num].cost_time = r;
bool input = vbusiness();
Person[person_num].identity = input;
cout << "请输入用户对此次银行服务体验的评价:" << endl;
cin >> Person[person_num].evaluate;
cout << "《=======********=======》" << endl;
system("pause");
system("cls");
enter_bank(Person[person_num]);
person_num++;
menu();
}
}
我们之前提到过我们系统的时间都是以分钟的形式进行运算以及比较的,以下就是转换过程
double temp = int(t - 9.0) * 60 + (t - int(t)) * 100;
而且我们系统是按照银行标准的时间进行运算的早上 8 点开始营业,17 点开始结业
如果不在合理范围就重新输入,如果小于上名客户的时间也重新输入(莫非时间能倒流?)
if (temp < time_now)
{
cout << "请按时间先后顺序输入" << endl;
system("pause");
system("cls");
continue;
}
由于我们用户办理业务所花费的时间是不知道的,所以我们设计成随机数更符合实际
int r = rand() % 30 + 1;//生成0到30的随机数
银行操作类的系列操作(查看窗口信息)
录入完用户后,我们就直接来到我们的取票操作:
void BankCard::enter_bank(user& p)
{
time_now = p.arrive_time; //新用户到达更新当前时间
check_leave(time_now); //检查当前时间下各窗口的情况
cout << "用户" << p.name << "在"; transform(p.arrive_time); cout << "到达了银行,";
cout << "办理业务需要花费" << p.cost_time << "分钟,用户身份是";
p.identity ? cout << "取钱用户" << endl : cout << "存钱用户" << endl;
show(); //展示当前时间各个窗口的情况
if (p.identity)
{
//若为取钱用户
p.enter_window = 3;
count_time(p);
if (p.leave_time > 480)
{
cout << "银行关门前不能办理完您的业务,请您次日再来" << endl << endl;
}
else
{
cout << "用户" << p.name << "为取钱用户,进入了取钱窗口" << endl << endl;
cout << "您排在取钱窗口的第" << window_VIP.size() + 1 << "号,大约需要等待" << p.wait_time << "分钟,请您耐心等候" << endl;
window_VIP.push(p);//加入到取钱队列中
show();
cout << endl << endl;
}
}
else
{
Window t[10];
for (int i = 0; i < sum; i++)
{
t[i].wait_user = window_normal[i].size();
t[i].num = i;
}
sort(t, t + sum, comp);
cout << "当前最少用户的窗口号是" << t[0].num + 1 << "号窗口" << endl;
p.enter_window = t[0].num;
count_time(p);
if (p.leave_time > 480)
{
cout << "银行关门前不能办理完您的业务,请您次日再来" << endl << endl;
}
else
{
cout << "用户" << p.name << "进入了" << p.enter_window + 1 << "号窗口" << endl;
cout << "您排在存钱窗口" << p.enter_window + 1 << "的第" << window_normal[p.enter_window].size() + 1 << "号,大约需要等待"
<< p.wait_time << "分钟,请您耐心等候" << endl;
window_normal[t[0].num].push(p);
show();
cout << endl << endl;
}
}
}
time_now = p.arrive_time;
我们之前说过我们的时间设定是根据最后一个客户的录入进行调整的,所以我们需要随时更新当前时间
if (p.leave_time > 480)
其次我们银行的标准是17点之后开始结业下班,而且我们系统的时间是以分钟进行计算的
所以我们这里需要小小的判断一下,要学会婉拒别人 ~ 哦
接下来就是最精华的时候了,我们客户进行排队吧,是个人都知道哪里人少排哪里,那我们怎么找到排队人数最少的那个窗口呢?
sort(t, t + sum, comp);
我们可以借助 sort 快排对自定义类型进行排升序,那么数组 0 的位置便是窗户最小的最优位置
检查队列中是否有离开的人
void BankCard::check_leave(int time)
{
int t_size1 = window_VIP.size();
while (t_size1--)
{
user temp = window_VIP.front();
if (temp.leave_time <= time_now)
{
window_VIP.pop();
cout << "用户" << temp.name << "在"; transform(temp.leave_time); cout << "离开了取钱号窗口" << endl;
}
else break;
}
for (int i = 0; i < sum; i++)
{
int t_size2 = window_normal[i].size();
while (t_size2--)
{
user temp = window_normal[i].front();
if (temp.leave_time <= time_now)
{
window_normal[i].pop();
cout << "用户" << temp.name << "在"; transform(temp.leave_time); cout << "离开了" << temp.enter_window + 1 << "号存钱窗口" << endl;
}
else break;
}
}
}
如果用户的离开时间小于我们的当前时间我们就弹出队列 ~
如果你还不知道离开时间怎么算,别急等下我教你
查看当前各窗口人数
void BankCard::show()
{
cout << "<><><><><><><><><><><><><><><><><><><>" << endl;
cout << "---*目前各窗口排队情况如下*---" << endl;;
cout << "<><><><><><><><><><><><><><>" << endl;
cout << "●● 取钱窗口等待人数:" << window_VIP.size() << "人 ●●" << endl;
for (int i = 0; i < sum; i++)
{
cout << "●● "<<i+1<<"号存钱窗口等待人数:" << window_normal[i].size() << "人 ●●" << endl;
}
cout << "*----------------------*" << endl;
}
计算用户离开时间以及更新等待时间
void BankCard::count_time(user& p)
{
if (p.enter_window == 3)
{
//进入的窗口为取钱窗口
if (!window_VIP.empty())
{
if (window_VIP.back().leave_time < p.arrive_time)
{
//离开时间=队列中上一位用户离开时间+花费时间
p.leave_time = p.arrive_time + p.cost_time;
}
else
{
p.leave_time = window_VIP.back().leave_time + p.cost_time;
}
}
else
{
p.leave_time = p.arrive_time + p.cost_time;//队列为 空离开时间=花费时间
}
p.wait_time = p.leave_time - p.arrive_time - p.cost_time;//更新等待时间
}
else
{
//为存钱窗口
if (!window_normal[p.enter_window].empty())
{
if (window_normal[p.enter_window].back().leave_time < p.arrive_time)
{
p.leave_time = p.arrive_time + p.cost_time;
}
else
{
p.leave_time = window_normal[p.enter_window].back().leave_time + p.cost_time;
}
}
else
{
p.leave_time = p.arrive_time + p.cost_time;//队列为空 离开时间=到达时间+花费时间
}
p.wait_time = p.leave_time - p.arrive_time - p.cost_time;//更新等待时间
}
}
可能老铁会有点懵 ~
if (p.enter_window == 3)
如果你仔细看就会发现我们在 enter_bank 中定义过
离开时间 = 队列中上一位用户离开时间 + 花费时间
银行操作类的查询排队
void BankCard::charts(int n)
{
cout << "●●●●●●●●●●●●●●" << endl;
cout << "●今日总共为" << n << "位顾客办理●" << endl;
cout << "●●●●●●●●●●●●●●" << endl;
cout << "用户名\t到达时间\t等待时间\t花费时间\t离开时间\t办理窗口\t评价" << endl;
for (int i = 0; i < n; i++) {
cout << Person[i].name << "\t";
transform(Person[i].arrive_time); cout << "\t\t";
cout << Person[i].wait_time << "\t\t";
cout << Person[i].cost_time << "\t\t";
transform(Person[i].leave_time); cout << "\t\t";
int num = Person[i].wait_time;
if (Person[i].enter_window == 3)
cout << "取钱窗口\t\t\t";
else
cout << "存钱窗口" << Person[i].enter_window + 1 << "\t";
cout << Person[i].evaluate << endl;
}
}
银行操作类的使用手册
void BankCard::handbook()
{
cout << "在日常生活中,我们普遍接触到窗口服务系统,如到银行柜台办理业务、景区现场购买门票等." << endl;
cout << "当需要办理业务的顾客数超过窗口数量时,我们需遵循排队等待原则。" << endl;
cout << "本系统集合多项功能,可以对窗口进行实时监控与调节:" << endl;
cout << "<1>用户到达营业厅,系统根据该用户所办理业务类型,自动分配到排队最短的窗口排队" << endl;
cout << "<2>业务办结,系统计算各窗口最先入队的顾客,该顾客办结业务并出队" << endl;
cout << "<3>查看各窗口排队情况,输出各窗口提供的业务类型,当前排队等待人数" << endl;
cout << "<4>当业务办结时,顾客可以对该窗口服务进行评分和建议,评分及建议" << endl;
cout << "<5>可统计当前排队人数最多的窗口业务类型,为新增窗口提供依据" << endl;
cout << "<6>可按评分高低顺序展示所有窗口" << endl;
cout << "<7>可按服务的顾客总数顺序展示所有窗口" << endl;
}
这个比较简单就是打印一段东西 ~ 这种代码多来一点就好了
银行操作类的存档文件
int BankCard::archived()
{
ofstream outFile;
outFile.open("score.txt", ios::out);
if (!outFile)
{
cout << "创建文件失败" << endl;
return 0;
}
int n = person_num;
outFile << "●●●●●●●●●●●●●●" << endl;
outFile << "●今日总共为" << n << "位顾客办理●" << endl;
outFile << "●●●●●●●●●●●●●●" << endl;
outFile << "用户名\t到达时间\t等待时间\t花费时间\t离开时间\t办理窗口\t评价" << endl;
for (int i = 0; i < n; i++) {
outFile << Person[i].name << "\t";
outFile << 9 + Person[i].arrive_time / 60 << ":" << Person[i].arrive_time % 60;
cout << "\t\t";
outFile << Person[i].wait_time << "\t\t";
outFile << Person[i].cost_time << "\t\t";
outFile << 9 + Person[i].leave_time / 60 << ":" << Person[i].leave_time % 60;
int num = Person[i].wait_time;
if (Person[i].enter_window == 3)
outFile << "取钱窗口\t\t\t";
else
outFile << "存钱通窗口" << Person[i].enter_window + 1 << "\t\t";
outFile << Person[i].evaluate << endl;
}
outFile.close();
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "存档成功,请到文件管理中查看详细" << endl;
return 1;
}
如果你学过 C++ 应该会很熟悉以上操作吧:就是把本应该输入到屏幕的输入到文件中
这里我模拟了一下存档的过程,有点简陋哈哈 ~
用记事本打开就是这个样子 ~ 老铁可以自己调整一下
银行操作类的增删操作
void BankCard::addition()
{
cout << "*------新增窗口中,请确保窗口没用用户排队------*" << endl;
int input;
cout << "(1.确认增加/0.退出操作):" << endl;
cin >> input;
if (input == 0) return;
sum++;
Queue<user>* newNode = new Queue<user>[sum];
window_normal->~Queue();
window_normal = newNode;
cout << "*新增窗口中,请等待*" << endl;
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "新增完成" << endl;
system("pause");
}
void BankCard::reduction()
{
cout << "*------删减窗口中,请确保窗口没用用户排队------*" << endl;
int input;
cout << "(1.确认删减/0.删减操作):" << endl;
cin >> input;
if (input == 0) return;
sum--;
Queue<user>* newNode = new Queue<user>[sum];
window_normal->~Queue();
window_normal = newNode;
cout << "*删减窗口中,请等待*" << endl;
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "删减完成" << endl;
system("pause");
}
银行操作类的暂停恢复
void BankCard::suspend()
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
cout << "\t\t\t温馨提示:请还在排队的客户稍等片刻" << endl;
cout << "\t\t\t<=====================================>" << endl;
while (true)
{
cout << endl << endl;
printf("\t\t\t*****************************************************\n");
printf("\t\t\t*---------------------------------------------------*\n");
printf("\t\t\t* 欢迎光临东方银行 *\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t********************系统功能菜单*********************\n");
printf("\t\t\t---------------------- --------------------------\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 1、录入客户信息 * 2、查看窗口信息 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 3、查询排队情况 * 4、退出排队系统 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 5、使用系统手册 * 6、存档系统文件 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 7、窗口状态新增 * 8、窗口状态删减 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 9、窗口业务暂停 * 0、窗口业务恢复 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t---------------------- --------------------------\n");
cout << "请输入你将要执行的操作>:" << endl;
int input;
cin >> input;
system("cls");
switch (input)
{
case 1:
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
break;
};
case 2:
{
show();
system("pause");
system("cls");
menu();
break;
};
case 3:
{
charts(person_num);
system("pause");
system("cls");
menu();
break;
};
case 4:
{
cout << "\t\t\t*-----------------------*" << endl;
cout << "\t\t\t<<><>欢迎使用本系统<><>>*" << endl;
cout << "\t\t\t*-----------------------*" << endl;
exit(0);
};
case 5:
{
handbook();
system("pause");
system("cls");
break;
}
case 6:
{
archived();
break;
}
case 7:
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
break;
}
case 8:
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
break;
}
case 9:
{
suspend();
break;
}
case 0:
cout << "*窗口业务恢复中,请等待*" << endl;
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "窗口业务恢复完成" << endl;
return;
}
}
}
以上的思路比较简单但是写的很烂,简单的说一下暂停,按下选项之间进入我们设置的循环里,限制了某一些功能,知道按恢复才能使用
银行操作类的全部代码
//user.h
#include<string>
#include"Queue.h"
using std::string;
class user
{
public:
string name; //用户编号
int arrive_time; //用户到达时间
bool identity; //顾客身份
int cost_time; //办理业务花费时间
int leave_time; //离开时间
int wait_time; //等待时间
int enter_window;//代表取钱窗口
};
//Window.h
class Window
{
public:
int num; //窗口号
int wait_user; //窗口等待人数
};
//Queue.h
template <typename T>
class QueueNode
{
public:
T data;
QueueNode* prev;
QueueNode* next;
};
template <typename T>
class Queue
{
public:
Queue();
~Queue();
bool empty() const
{
return _size == 0;
}
int size() const
{
return _size;
}
void push(const T&x);
void pop();
T front();
T back();
private:
QueueNode<T>* head;
QueueNode<T>* tail;
int _size;
};
template <typename T>
Queue<T>::Queue()
{
head = new QueueNode <T>;
tail = new QueueNode <T>;
head->prev = NULL;
head->next = tail;
tail->prev = head;
tail->next = NULL;
_size = 0;
}
template <typename T>
Queue<T>::~Queue()
{
while (_size != 0)
{
QueueNode<T>* t;
t = head->next;
head->next = head->next->next;
head->next->prev = head;
delete t;
_size--;
}
}
template <typename T>
void Queue<T>::push(const T& x)
{
QueueNode<T>* t = new QueueNode<T>;
t->data = x;
t->prev = tail->prev;
t->next = tail;
tail->prev->next = t;
tail->prev = t;
_size++;
}
template <typename T>
void Queue<T>::pop()
{
if (_size)
{
QueueNode<T>* t;
t = head->next;
head->next = head->next->next;
head->next->prev = head;
delete t;
_size--;
}
}
template <typename T>
T Queue<T>::front()
{
return head->next->data;
}
template <typename T>
T Queue<T>::back()
{
return tail->prev->data;
}
//BankCard.h
#include <iostream>
#include"user.h"
#include"Window .h"
#include<algorithm>
#include<time.h>
#include<cstdio>
#include<conio.h>
#include <fstream>
#include<windows.h>
using namespace std;
class BankCard
{
public:
//初始化
void BankCard_init();
//构造函数
BankCard()
{
BankCard_init();
}
//手册
void handbook();
//查看窗口人数
void show();
//计算离开时间和更新等待时间
void count_time(user& p);
//检查队列中是否有离开的人
void check_leave(int time);
//进入银行取票
void enter_bank(user& p);
//打印表单
void charts(int n);
//用户入队列
void manual();
//菜单-选项
void menu();
//新增窗口
void addition();
//删减窗口
void reduction();
//窗口暂停
void suspend();
//存档文件
int archived();
//办理的业务类型
int vbusiness();
};
//BankCard.cpp
#include"BankCard.h"
Queue<user>* window_normal = new Queue<user>[3];
static int sum = 3;
Queue<user> window_VIP;
Queue<user> leave;
user Person[1000];
int time_now;
int person_num;
bool comp(Window x, Window y)
{
if (x.wait_user == y.wait_user)
{
return x.num < y.num;
}
return x.wait_user < y.wait_user;
}
void BankCard::BankCard_init()
{
time_now = 0;
person_num = 0;
for (int i = 0; i < sum; i++)
{
while (!window_normal[i].empty())
{
window_normal[i].pop();
}
}
while (!window_VIP.empty())
{
window_VIP.pop();
}
while (!leave.empty())
{
leave.pop();
}
}
void transform(int num)
{
cout << 9 + num / 60 << ":" << num % 60;
}
void BankCard::show()
{
cout << "<><><><><><><><><><><><><><><><><><><>" << endl;
cout << "---*目前各窗口排队情况如下*---" << endl;;
cout << "<><><><><><><><><><><><><><>" << endl;
cout << "●● 取钱窗口等待人数:" << window_VIP.size() << "人 ●●" << endl;
for (int i = 0; i < sum; i++)
{
cout << "●● "<<i+1<<"号存钱窗口等待人数:" << window_normal[i].size() << "人 ●●" << endl;
}
cout << "*----------------------*" << endl;
}
void BankCard::count_time(user& p)
{
if (p.enter_window == 3)
{
if (!window_VIP.empty())
{
if (window_VIP.back().leave_time < p.arrive_time)
{
p.leave_time = p.arrive_time + p.cost_time;
}
else
{
p.leave_time = window_VIP.back().leave_time + p.cost_time;
}
}
else
{
p.leave_time = p.arrive_time + p.cost_time;
}
p.wait_time = p.leave_time - p.arrive_time - p.cost_time;
}
else
{
if (!window_normal[p.enter_window].empty())
{
if (window_normal[p.enter_window].back().leave_time < p.arrive_time)
{
p.leave_time = p.arrive_time + p.cost_time;
}
else
{
p.leave_time = window_normal[p.enter_window].back().leave_time + p.cost_time;
}
}
else
{
p.leave_time = p.arrive_time + p.cost_time;
}
p.wait_time = p.leave_time - p.arrive_time - p.cost_time;
}
}
void BankCard::check_leave(int time)
{
int t_size1 = window_VIP.size();
while (t_size1--)
{
user temp = window_VIP.front();
if (temp.leave_time <= time_now)
{
window_VIP.pop();
cout << "用户" << temp.name << "在"; transform(temp.leave_time); cout << "离开了取钱号窗口" << endl;
}
else break;
}
for (int i = 0; i < sum; i++)
{
int t_size2 = window_normal[i].size();
while (t_size2--)
{
user temp = window_normal[i].front();
if (temp.leave_time <= time_now)
{
window_normal[i].pop();
cout << "用户" << temp.name << "在"; transform(temp.leave_time); cout << "离开了" << temp.enter_window + 1 << "号存钱窗口" << endl;
}
else break;
}
}
}
void BankCard::enter_bank(user& p)
{
time_now = p.arrive_time;
check_leave(time_now);
cout << "用户" << p.name << "在"; transform(p.arrive_time); cout << "到达了银行,";
cout << "办理业务需要花费" << p.cost_time << "分钟,用户身份是";
p.identity ? cout << "取钱用户" << endl : cout << "存钱用户" << endl;
show();
if (p.identity)
{
p.enter_window = 3;
count_time(p);
if (p.leave_time > 480)
{
cout << "银行关门前不能办理完您的业务,请您次日再来" << endl << endl;
}
else
{
cout << "用户" << p.name << "为取钱用户,进入了取钱窗口" << endl << endl;
cout << "您排在取钱窗口的第" << window_VIP.size() + 1 << "号,大约需要等待" << p.wait_time << "分钟,请您耐心等候" << endl;
window_VIP.push(p);
show();
cout << endl << endl;
}
}
else
{
Window t[10];
for (int i = 0; i < sum; i++)
{
t[i].wait_user = window_normal[i].size();
t[i].num = i;
}
sort(t, t + sum, comp);
cout << "当前最少用户的窗口号是" << t[0].num + 1 << "号窗口" << endl;
p.enter_window = t[0].num;
count_time(p);
if (p.leave_time > 480)
{
cout << "银行关门前不能办理完您的业务,请您次日再来" << endl << endl;
}
else
{
cout << "用户" << p.name << "进入了" << p.enter_window + 1 << "号窗口" << endl;
cout << "您排在存钱窗口" << p.enter_window + 1 << "的第" << window_normal[p.enter_window].size() + 1 << "号,大约需要等待"
<< p.wait_time << "分钟,请您耐心等候" << endl;
window_normal[t[0].num].push(p);
show();
cout << endl << endl;
}
}
}
void BankCard::charts(int n)
{
cout << "●●●●●●●●●●●●●●" << endl;
cout << "●今日总共为" << n << "位顾客办理●" << endl;
cout << "●●●●●●●●●●●●●●" << endl;
cout << "用户名\t到达时间\t等待时间\t花费时间\t离开时间\t办理窗口\t评价" << endl;
for (int i = 0; i < n; i++) {
cout << Person[i].name << "\t";
transform(Person[i].arrive_time); cout << "\t\t";
cout << Person[i].wait_time << "\t\t";
cout << Person[i].cost_time << "\t\t";
transform(Person[i].leave_time); cout << "\t\t";
int num = Person[i].wait_time;
if (Person[i].enter_window == 3)
cout << "取钱窗口\t\t\t";
else
cout << "存钱窗口" << Person[i].enter_window + 1 << "\t";
cout << Person[i].evaluate << endl;
}
}
void BankCard::manual()
{
while (1)
{
double t;
cout << "*-----------------------*" << endl;
cout << "《=======姓名=======》"; cin >> Person[person_num].name;
cout << "《=======到达时间=======》"; cin >> t;
double temp = int(t - 9.0) * 60 + (t - int(t)) * 100;
if (temp < time_now)
{
cout << "请按时间先后顺序输入" << endl;
system("pause");
system("cls");
continue;
}
Person[person_num].arrive_time = temp;
int r = rand() % 30 + 1;
Person[person_num].cost_time = r;
bool input = vbusiness();
Person[person_num].identity = input;
cout << "请输入用户对此次银行服务体验的评价:" << endl;
cin >> Person[person_num].evaluate;
cout << "《=======********=======》" << endl;
system("pause");
system("cls");
enter_bank(Person[person_num]);
person_num++;
menu();
}
}
void BankCard::handbook()
{
cout << "在日常生活中,我们普遍接触到窗口服务系统,如到银行柜台办理业务、景区现场购买门票等." << endl;
cout << "当需要办理业务的顾客数超过窗口数量时,我们需遵循排队等待原则。" << endl;
cout << "本系统集合多项功能,可以对窗口进行实时监控与调节:" << endl;
cout << "<1>用户到达营业厅,系统根据该用户所办理业务类型,自动分配到排队最短的窗口排队" << endl;
cout << "<2>业务办结,系统计算各窗口最先入队的顾客,该顾客办结业务并出队" << endl;
cout << "<3>查看各窗口排队情况,输出各窗口提供的业务类型,当前排队等待人数" << endl;
cout << "<4>当业务办结时,顾客可以对该窗口服务进行评分和建议,评分及建议" << endl;
cout << "<5>可统计当前排队人数最多的窗口业务类型,为新增窗口提供依据" << endl;
cout << "<6>可按评分高低顺序展示所有窗口" << endl;
cout << "<7>可按服务的顾客总数顺序展示所有窗口" << endl;
}
void BankCard::menu()
{
while (true)
{
printf("\t\t\t*****************************************************\n");
printf("\t\t\t*---------------------------------------------------*\n");
printf("\t\t\t* 欢迎光临东方银行 *\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t********************系统功能菜单*********************\n");
printf("\t\t\t---------------------- --------------------------\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 1、录入客户信息 * 2、查看窗口信息 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 3、查询排队情况 * 4、退出排队系统 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 5、使用系统手册 * 6、存档系统文件 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 7、窗口状态新增 * 8、窗口状态删减 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 9、窗口业务暂停 * 0、窗口业务恢复 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t---------------------- --------------------------\n");
cout << "请输入你将要执行的操作>:" << endl;
int input;
cin >> input;
system("cls");
switch (input)
{
case 1:
{
manual();
system("pause");
system("cls");
break;
};
case 2:
{
show();
system("pause");
system("cls");
menu();
break;
};
case 3:
{
charts(person_num);
system("pause");
system("cls");
menu();
break;
};
case 4:
{
cout << "*-----------------------*" << endl;
cout << "<<><>欢迎使用本系统<><>>*" << endl;
cout << "*-----------------------*" << endl;
exit(0);
};
case 5:
{
handbook();
system("pause");
system("cls");
break;
}
case 6:
{
archived();
system("pause");
system("cls");
break;
}
case 7:
{
addition();
system("pause");
system("cls");
break;
}
case 8:
{
reduction();
system("pause");
system("cls");
break;
}
case 9:
{
suspend();
system("pause");
system("cls");
break;
}
}
}
}
void BankCard::addition()
{
cout << "*------新增窗口中,请确保窗口没用用户排队------*" << endl;
int input;
cout << "(1.确认增加/0.退出操作):" << endl;
cin >> input;
if (input == 0) return;
sum++;
Queue<user>* newNode = new Queue<user>[sum];
window_normal->~Queue();
window_normal = newNode;
cout << "*新增窗口中,请等待*" << endl;
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "新增完成" << endl;
system("pause");
}
void BankCard::reduction()
{
cout << "*------删减窗口中,请确保窗口没用用户排队------*" << endl;
int input;
cout << "(1.确认删减/0.删减操作):" << endl;
cin >> input;
if (input == 0) return;
sum--;
Queue<user>* newNode = new Queue<user>[sum];
window_normal->~Queue();
window_normal = newNode;
cout << "*删减窗口中,请等待*" << endl;
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "删减完成" << endl;
system("pause");
}
int BankCard::vbusiness()
{
cout << "*-----------------------*" << endl;
cout << "<<><>0.办理存钱窗口<><>>*" << endl;
cout << "<<><>1.办理取钱窗口<><>>*" << endl;
cout << "*-----------------------*" << endl;
int input;
cout << "请输入你想办理的业务>:" << endl;
cin >> input;
if (input == 0) return 0;
if (input == 1) return 1;
}
void BankCard::suspend()
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
cout << "\t\t\t温馨提示:请还在排队的客户稍等片刻" << endl;
cout << "\t\t\t<=====================================>" << endl;
while (true)
{
cout << endl << endl;
printf("\t\t\t*****************************************************\n");
printf("\t\t\t*---------------------------------------------------*\n");
printf("\t\t\t* 欢迎光临东方银行 *\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t********************系统功能菜单*********************\n");
printf("\t\t\t---------------------- --------------------------\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 1、录入客户信息 * 2、查看窗口信息 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 3、查询排队情况 * 4、退出排队系统 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 5、使用系统手册 * 6、存档系统文件 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 7、窗口状态新增 * 8、窗口状态删减 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t** 9、窗口业务暂停 * 0、窗口业务恢复 **\n");
printf("\t\t\t*****************************************************\n");
printf("\t\t\t---------------------- --------------------------\n");
cout << "请输入你将要执行的操作>:" << endl;
int input;
cin >> input;
system("cls");
switch (input)
{
case 1:
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
break;
};
case 2:
{
show();
system("pause");
system("cls");
menu();
break;
};
case 3:
{
charts(person_num);
system("pause");
system("cls");
menu();
break;
};
case 4:
{
cout << "\t\t\t*-----------------------*" << endl;
cout << "\t\t\t<<><>欢迎使用本系统<><>>*" << endl;
cout << "\t\t\t*-----------------------*" << endl;
exit(0);
};
case 5:
{
handbook();
system("pause");
system("cls");
break;
}
case 6:
{
archived();
break;
}
case 7:
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
break;
}
case 8:
{
cout << "\t\t\t《===================窗口业务暂停中===================》" << endl;
break;
}
case 9:
{
suspend();
break;
}
case 0:
cout << "*窗口业务恢复中,请等待*" << endl;
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "窗口业务恢复完成" << endl;
return;
}
}
}
int BankCard::archived()
{
ofstream outFile;
outFile.open("score.txt", ios::out);
if (!outFile)
{
cout << "创建文件失败" << endl;
return 0;
}
int n = person_num;
outFile << "●●●●●●●●●●●●●●" << endl;
outFile << "●今日总共为" << n << "位顾客办理●" << endl;
outFile << "●●●●●●●●●●●●●●" << endl;
outFile << "用户名\t到达时间\t等待时间\t花费时间\t离开时间\t办理窗口\t评价" << endl;
for (int i = 0; i < n; i++) {
outFile << Person[i].name << "\t";
outFile << 9 + Person[i].arrive_time / 60 << ":" << Person[i].arrive_time % 60;
cout << "\t\t";
outFile << Person[i].wait_time << "\t\t";
outFile << Person[i].cost_time << "\t\t";
outFile << 9 + Person[i].leave_time / 60 << ":" << Person[i].leave_time % 60;
int num = Person[i].wait_time;
if (Person[i].enter_window == 3)
outFile << "取钱窗口\t\t\t";
else
outFile << "存钱通窗口" << Person[i].enter_window + 1 << "\t\t";
outFile << Person[i].evaluate << endl;
}
outFile.close();
cout << "====>" << endl;
Sleep(3000);
cout << "==========>" << endl;
cout << "==================>" << endl;
Sleep(2000);
cout << "===========================>" << endl;
cout << "=====================================>" << endl;
Sleep(1000);
cout << "===============================================================>" << endl;
cout << "存档成功,请到文件管理中查看详细" << endl;
return 1;
}
//main.cpp
#include"BankCard.h"
#include <graphics.h>
void menu2()
{
int input = 0, count = 0, i = 0;
char mima[20] = "123";//登入的密码
char shuru[20] = { 0 };
system("color F4");
printf("\t\t\t **************************************\n");
printf("\t\t\t | *欢迎光临东方银行* |\n");
printf("\t\t\t | *管理员: 东方* |\n");
printf("\t\t\t ------------------------------------\n");
printf("请输入管理员密码:\n");
while ((count = _getch()) != '\r')
{
if (count == '\b')
{
i--;
printf("\b \b");
}
else
{
shuru[i++] = count;
printf("*");
}
}
shuru[i++] = '\0';
if (strcmp(mima, shuru) == 0)
{
printf("\n密码正确,您已进入系统!\n");
}
else
{
printf("\n密码错误,请重新输入!\n");
exit(0); //输入错误,直接退出
}
system("pause");
system("cls");
}
int main()
{
system("color F4");
menu2();
BankCard bk;
bk.BankCard_init();
bk.menu();
return 0;
}