实验目的
假设某银行有四个窗口对外接待客户,从早晨银行开门起不断有客户进入银行 由于每个窗口在某个时刻只能接待一个客户,因此在客户人数众多时需在每个窗口前顺次排队,对于刚进入银行的客户,如果某个窗口的业务员正空闲,则可上前办理业务,反之,若四个窗口均有客户所占,他便会排在人数最少的队伍后面。现在编制一个程序以模拟银行的这种业务活动并计算一天中客户在银行逗留的平均时间。
实验原理
- 实现初始化(OpenForDay),模拟银行开门时各数据结构数据结构的状态。包括初始化四个队列。
- 事件驱动(EventDrived),对客户到达和离开事件做相应处理。用一个switch语句来供管理员选择处理什么事件。
- 下班处理(CloseForDay),模拟银行关门的动作,消除四个队列,并统计客户平均逗留时间。
- 分别用用链队列模拟四个窗口前面人们所排的队伍,再用两个结构体表示时间和客户。可以用来统计每个客户在银行逗留的时间。
要点复习
什么是指针?
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:
Client *p=new Client; //定义一个Client类型的指针。
什么是结构体?
结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。接下来我们来定义一个结构体:
struct Time//构建一个表示时间的结构体
{
int gettime_hour;
int gettime_minute;
int gotime_hour;
int gotime_minute;
int serivetime;
};
如果两个结构体互相包含,则需要对其中一个结构体进行不完整声明:
typedef struct Client//构建一个客户的链队列来表示队伍
{
Time t;
struct Client *next; //自己包含一个跟自己类型一样的指针。
int num;
}*Queueptr;
具体代码
在这里插入代码片
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
struct Time//构建一个表示时间的结构体
{
int gettime_hour;
int gettime_minute;
int gotime_hour;
int gotime_minute;
int serivetime;
};
typedef struct Array
{
int num;
int length;
};
typedef struct Client//构建一个客户的链队列来表示队伍
{
Time t;
struct Client *next;
int num;
}*Queueptr;
typedef struct
{
Client client;
Queueptr front;
Queueptr rear;
}LinkQueue;
int InitQueue(LinkQueue &Q) { //初始化队列
Q.front = Q.rear = new Client;
if (!Q.front) {
printf("初始化失败!\n");
return NO;
}
Q.front->next = NULL;
Q.client.t.gettime_hour = 0;
Q.client.t.gettime_minute = 0;
Q.client.t.gotime_hour = 0;
Q.client.t.gotime_minute = 0;
Q.client.t.serivetime = 0;
printf("初始化成功!\n");
return OK;
}
int EnQueue(LinkQueue &Q,int value) {//客户达到银行执行入队操作
Client *p=new Client;
p->num = value;
int hour, minute;
printf("请输入该客户的到达时间(格式为:几时几分):\n");
scanf_s("%d%d", &hour, &minute);
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
Q.client.t.gettime_hour = hour;
Q.client.t.gettime_minute = minute;
Q.client.num = value;
return 1;
}
void DestroyQueue(LinkQueue &Q) {//销毁队列
while (Q.front)
{
Q.rear = Q.front->next;
delete(Q.front);
Q.front = Q.rear;
}
printf("该队列已销毁\n");
}
int EmptyQueue(LinkQueue Q) {//判断队列是否为空,可以省略不写
if (Q.front == Q.rear) {
printf("该队列为空。\n");
return 1;
}
printf("该队列不为空。\n");
return 0;
}
int OutQueue(LinkQueue &Q) { //客户离开银行,执行出队操作
int hour;
int mi;
int value;
printf("请输入第%d号客户离开的时间(几时几分):",Q.client.num);
scanf_s("%d%d", &hour, &mi);
Q.client.t.gotime_hour = hour;
Q.client.t.gotime_minute = mi;
Q.client.t.serivetime = (Q.client.t.gotime_hour - Q.client.t.gettime_hour) * 60 + Q.client.t.gotime_minute - Q.client.t.gettime_minute;
int tt = Q.client.t.serivetime;
if (EmptyQueue(Q) == 1)
return 0;
Queueptr p = Q.front->next;
value = p->num;
Q.front->next = p->next;
if (Q.rear == p) {
Q.rear = Q.front;
}
delete p;
printf("第%d号客户已经离开。\n",value);
return tt;
}
//银行开始营业
void OpenForDay(LinkQueue &Q1, LinkQueue &Q2,LinkQueue &Q3, LinkQueue &Q4) {
printf("初始化第一个窗口,");
InitQueue(Q1);
printf("初始化第二个窗口,");
InitQueue(Q2);
printf("初始化第三个窗口,");
InitQueue(Q3);
printf("初始化第四个窗口,");
InitQueue(Q4);
}
//每当要执行操作命令时,执行该函数
int EventDrived(LinkQueue &Q1, LinkQueue &Q2, LinkQueue &Q3, LinkQueue &Q4, double *NumOfClients, double *tot_time,int *flag) {
printf("+----------------------------------+\n");
printf("| |\n");
printf("| 1->新客户到来 |\n");
printf("| 2->客户离开 |\n");
printf("| 3->停止营业 |\n");
printf("| |\n");
printf("+----------------------------------+\n");
int action=0;
printf("请输入:");
fflush(stdin);
scanf_s("%d", &action);
while (action <= 0 || action > 3) {
printf("不符合要求,请重新输入:");
scanf_s("%d", &action);
}
switch (action) {
case 1:
if (Q1.rear - Q1.front == 0) {
printf("请客户去1号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q1, *NumOfClients);
break;
}
else if (Q2.rear - Q2.front == 0) {
printf("请客户去2号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q2, *NumOfClients);
break;
}
else if (Q3.rear - Q3.front == 0) {
printf("请客户去3号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q3, *NumOfClients);
break;
}
else if (Q4.rear - Q4.front == 0) {
printf("请客户去4号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q4, *NumOfClients);
break;
}
else if (Q1.rear - Q1.front <= Q2.rear - Q2.front&&Q1.rear - Q1.front <= Q3.rear - Q3.front&&Q1.rear - Q1.front <= Q4.rear - Q4.front)
{
printf("请客户去1号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q1, *NumOfClients);
break;
}
else if (Q2.rear - Q2.front < Q1.rear - Q1.front&&Q2.rear - Q2.front <= Q3.rear - Q3.front&&Q2.rear - Q2.front <= Q4.rear - Q4.front)
{
printf("请客户去2号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q2, *NumOfClients);
break;
}
else if ((Q3.rear - Q3.front < Q1.rear - Q1.front&&Q3.rear - Q3.front < Q1.rear - Q1.front&&Q3.rear - Q3.front <= Q4.rear - Q4.front))
{
printf("请客户去3号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q3, *NumOfClients);
break;
}
else if (Q4.rear - Q4.front < Q1.rear - Q1.front&&Q4.rear - Q4.front < Q3.rear - Q3.front&&Q4.rear - Q4.front < Q2.rear - Q2.front)
{
printf("请客户去4号窗口排队!");
*NumOfClients = *NumOfClients + 1;
EnQueue(Q4, *NumOfClients);
break;
}
case 2:
int a;
printf("请输入第几号窗口的客户离开:");
scanf_s("%d", &a);
if (a == 1)
{
*tot_time = *tot_time + OutQueue(Q1);
break;
}
else if (a == 2)
{
*tot_time = *tot_time + OutQueue(Q2);
break;
}
else if (a == 3)
{
*tot_time = *tot_time + OutQueue(Q3);
break;
}
else if (a == 4)
{
*tot_time = *tot_time + OutQueue(Q4);
break;
}
else
{
printf("输入错误!\n");
break;
}
case 3:
*flag = 1;
return 1;
}
return 0;
}
//关门停止营业操作,并计算每个客户平均逗留的时间
double CloseForDay(LinkQueue &Q1, LinkQueue &Q2, LinkQueue &Q3, LinkQueue &Q4, double *NumOfClients, double *tot_time)
{
DestroyQueue(Q1);
DestroyQueue(Q2);
DestroyQueue(Q3);
DestroyQueue(Q4);
double T;
double N;
T = *tot_time;
N = *NumOfClients;
double AVE = T / N;
printf("停止营业,今天银行里的客户平均逗留时间为:%f\n",AVE);
return 0;
}
int main()
{
LinkQueue Q1;
LinkQueue Q2;
LinkQueue Q3;
LinkQueue Q4;
int InitQueue(LinkQueue &Q);
int EnQueue(LinkQueue &Q, int value);
void DestroyQueue(LinkQueue &Q);
int EmptyQueue(LinkQueue Q);
int OutQueue(LinkQueue &Q);
double NumOfClients = 0;
double tot_time = 0;
int flag=0;
int EventDrived(LinkQueue &Q1, LinkQueue &Q2, LinkQueue &Q3, LinkQueue &Q4, double *NumOfClients, double *tot_time, int *flag);
void OpenForDay(LinkQueue &Q1, LinkQueue &Q2, LinkQueue &Q3, LinkQueue &Q4);
double CloseForDay(LinkQueue &Q1, LinkQueue &Q2, LinkQueue &Q3, LinkQueue &Q4, double *NumOfClients, double *tot_time);
OpenForDay(Q1, Q2, Q3, Q4);
while (flag==0) {
EventDrived(Q1, Q2, Q3, Q4, &NumOfClients, &tot_time, &flag);
}
CloseForDay(Q1, Q2, Q3, Q4,&NumOfClients, &tot_time);
system("pause");
return 0;
}
小结
我个人觉得其实在实现这种实验的时候,其实用C++可以把整体代码写得更好,更简单,而C语言可能有点古老,比较繁琐,也欢迎小伙伴们前来讨论,指出不足。
如果这篇文章对你有所帮助~
欢迎关注我的公众号**夏虫不可语冰也**
同时也欢迎访问我的个人网站 www.cjl946.com
这里有更多你需要的信息哦~