银行取号机
(1)设计思路:每个银行都有若干个柜台,初始时建一个队列数组,保存各个柜台的工作信息。
使用对象:银行职员处理业务,客户办理业务。
客户取号办理业务,应该选择排队人数最少的柜台进行排队。每个客户看作一个结点,每个结点中包括该客户的编号和指向下一个结点的指针。为每个柜台构造一个队列,存放队列的头尾指针和队列的人数。
(2)实现的功能:
1.客户的取号
2.删除号码
3.查看当前排队信息
4.银行管理柜台(仅限银行职员使用)
*使用时需要输入密码
*进入后可以选择柜台叫号、关闭柜台、查看当前柜台工作信息
(3)结构体定义
typedef struct person {
int num; //客户拿到的号码
struct person *next;
}person, *personPtr;
typedef struct {
personPtr front;
personPtr rear;
int count; //队列的人数
}LinkQueue;
int queueNum; //当前队列的数量
LinkQueue s[COUNTERNUM+1];
(4)宏定义及函数
#define COUNTERNUM 5
#define OVERFLOW -2
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
void InitQueue()//构造空队列
void DestroyQueue(int x) //销毁队列
void printQueue(int x) //打印客户排队信息
void EnQueue() //插入元素为新的队尾元素
void call(int n) //n号柜台叫号,即客户出队
void delnum(int cnum, int num) //客户删除自己的号码
void select()//查询当前柜台信息
void menu()//菜单界面
void login()//银行职员登陆
void endwork()//结束柜台工作
void startwork()//启动柜台叫号
void printcounter()//打印当前柜台工作信息
void bankmenu()//银行操作柜台菜单界面
void bank()//银行工作
(5)功能实现
功能选择界面
取号
删除自己的号码
查看当前排队信息
柜台操作
查看柜台工作信息
柜台叫号
柜台结束工作
源码
#pragma warning(disable:4996)
#define COUNTERNUM 5
#define OVERFLOW -2
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
typedef struct person {
int num; //客户拿到的号码
struct person *next;
}person, *personPtr;
typedef struct {
personPtr front;
personPtr rear;
int count; //队列的人数
}LinkQueue;
int queueNum; //当前队列的数量
LinkQueue s[COUNTERNUM+1];
//int workFlag[COUNTERNUM + 1];
void InitQueue() {//构造空队列
LinkQueue q;
q.front = q.rear = (personPtr)malloc(sizeof(person));
if (!q.front)exit(OVERFLOW);
q.front->next = NULL;
s[queueNum + 1] = q; //队列从1开始编号
s[queueNum + 1].count = 0;
queueNum++;
}
void DestroyQueue(int x) {
//销毁队列
LinkQueue Q = s[x];
while (Q.front) {
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
queueNum--;
}
void printQueue(int x) {//打印客户排队信息
printf("您已在%d号柜台排队\n", x);
printf("您的号码为%d,请耐心等待\n\n", s[x].count);
}
void EnQueue() {//插入元素为新的队尾元素
personPtr p = (personPtr)malloc(sizeof(person));
if (!p)exit(OVERFLOW);
if (queueNum < COUNTERNUM) { //如果此时有空余的柜台则创建一个新的队列
InitQueue(); //构造了一个空队列
p->num = 1;//P为队列的第一个人,编号为1
s[queueNum].rear->next = p;
s[queueNum].rear = p;
p->next = NULL;
s[queueNum].count++;
int x = queueNum;
printQueue(x);
}
else { //柜台已满,在所有柜台中查找人数最少的进行插入
int min = s[1].count;
int x=1;
for (int i = 2; i <= COUNTERNUM; i++) {
if (s[i].count < min)
{
min = s[i].count;
x = i;
}//if
}//for
//找到人数最少的队列之后进行插入
s[x].rear->next = p;
s[x].rear = p;
p->next = NULL;
s[x].count++;
p->num = s[x].count;
printQueue(x);
}//else
}
void call(int n) {//n号柜台叫号,即客户出队
LinkQueue Q = s[n];
if (Q.front == Q.rear) {
printf("%d号柜台叫号完毕\n", n);
return;
}
if (Q.count==1) {
Q.rear = Q.front;
s[n].count = 0;
printf("请%d号柜台%d号客户办理业务\n", n,1);
return;
}//队列中只有一个人
personPtr p = Q.front->next;
while(p) {
printf("请%d号柜台%d号客户办理业务\n", n, p->num);
p = p->next;
s[n].count--;
}
printf("%d号柜台叫号结束\n\n",n);
}
void delnum(int cnum, int num) {//客户删除自己的号码
if (cnum > queueNum) {
printf("输入有误,该柜台没有工作\n");
return;
}
LinkQueue Q = s[cnum];
personPtr p ;
p = s[cnum].front->next;
personPtr pre;
pre = s[cnum].front;
if (num > Q.count) {
printf("输入有误,您的号码不在此柜台队列中\n");
return;
}
if(Q.count == 1) {
if (p->num != num) {
printf("输入有误,您的号码不在此柜台队列中\n");
return;
}
s[cnum].count = 0;
s[cnum].front= s[cnum].rear;
s[cnum].rear->next = NULL;
printf("删除成功!\n");
}
else {
while (p->next != NULL) {
if (p->num == num) {
pre->next = p->next;
free(p);
p = NULL;
break;
}
else {
p = p->next;
pre = pre->next;
}
}
if (p != NULL) {
if (p->num == num) {
pre->next = p->next;
free(p);
p = NULL;
}
}
s[cnum].count--;
printf("删除成功!\n");
}
}
void select() {
if (queueNum == 0) {
printf("当前无排队队列\n");
}
else {
printf("当前排队的队列有:\n");
for (int i = 1; i <= COUNTERNUM; i++) {
if(s[i].front!= s[i].rear)
printf("队列%d,人数%d\n", i, s[i].count);
}
}
}
void menu() {
printf("\n\n欢迎使用银行取号机\n");
printf("1.取号\n");
printf("2.删除号码\n");
printf("3.查看当前排队信息\n");
printf("4.柜台工作安排(仅限银行职员使用)\n\n\n");
}
void login() {
char psword[20] = "0000"; //设置原始密码为0000
char inpsw[20];
int q = 0;
printf("请输入登录密码************\n");
scanf("%s", inpsw);
if (strcmp(psword, inpsw) != 0) { //验证密码是否正确
q = 1;
printf("密码错误,请重新输入\n");
while (q = 1) {
scanf("%s", inpsw);
if (strcmp(psword, inpsw) == 0)break;
else printf("密码错误,请重新输入\n");
}
}
printf("密码正确,欢迎使用银行取号机\n\n");//若密码正确则进入学生信息系统
}
void endwork() {
printf("请输入要结束工作的柜台编号\n");
int a;
scanf("%d", &a);
DestroyQueue(a);
printf("%d号柜台开始休息\n\n",a);
}
void startwork() {
printf("请输入要开始叫号的柜台编号\n");
int cnum;
scanf("%d", &cnum);
printf("%d号柜台开始叫号,请在%d号柜台排队等候的客户注意\n\n\n", cnum, cnum);
call(cnum);
}
void printcounter() {
if (queueNum == 0)printf("当前无柜台在工作\n");
else {
printf("当前工作的柜台:\n");
for (int i = 1; i <= COUNTERNUM; i++) {
if (s[i].front != s[i].rear)
printf("%d号\n", i);
}
}
}
void bankmenu() {
while (1) {
printf("请选择你要进行的操作\n");
printf("1.柜台开始叫号\n");
printf("2.柜台结束工作\n");
printf("3.查看当前柜台工作情况\n");
printf("4.返回\n");
int choice;
scanf("%d", &choice);
switch (choice) {
case 1: startwork(); break;
case 2: endwork(); break;
case 3:printcounter(); break;
default:return;
}
}
}
void bank() {
login();
bankmenu();
}
int main() {
while (1) {
menu();
int choice;
scanf("%d", &choice);
switch (choice)
{
case 1:EnQueue(); break;
case 2:printf("请输入柜台号和您的排队号码\n");
int cnum, num;
scanf("%d%d", &cnum, &num);
delnum(cnum, num);
break;
case 3:select();
break;
case 4:bank();
break;
default:printf("输入有误!\n");
break;
}
}
}