main.c
/*************************************************************
题目:电话客户服务模拟
1、问题描述
一个模拟时钟提供接听电话服务的时间(以分钟计),然后这个时
钟将循环地自增1(分钟),直到到达指定的时间为止。在时钟的每
个“时刻”,就会执行一次检查来看看当前电话的服务是否已经完成,
如果是,这个电话从电话队列中删除,模拟服务将从队列中取出下
一个电话(如果有)继续开始。同时还需要执行一个检查来判断是
否有一个新的电话到达,如果有将其到达的时间记录下来,并为其
产生一个随机服务时间,这个服务时间也被记录下来,然后将这个
电话放入电话队列中,当客户服务人员空闲时,按照先来先服务的
方式处理这个队列。当时钟到达指定时间时,不会再接听新电话,
但是服务将继续,直到队列中所有电话得到处理为止。
2、要求
(1)程序需要处理的初始数据包括:客户服务人员的人数
、时间限制,电话到达的速率,平均服务时间。
(2)程序产生的结果包括:处理的电话数,每个电话的平
均等待时间
运行环境:windows Code::blocks
*************************************************************/
#include #include #include "queue.h"
/**需要输入的数据*/
int customer_service_staff_num = 5;//客户服务人员的人数
time_t time_limite = 20;//时间限制
double telephone_rate = 60.0/60;//电话到达的速率
/*此处为简化程序默认通电时间在0到2倍平均时间之间均匀分布*/
int average_service_time = 10;//平均服务时间
/**其他全局变量*/
time_t start_time;//记录开始时间
time_t t;//上次时间
int period_time;//电话到达的周期
time_t rawtime;//当前时间,以秒计,从1970年1月一日起算
queue tel_wait_que;//电话等待队列
int wait_time_sum = 0;//等待时间
int phone_sum = 0;//电话计数
int phone_service_finished = 0;//电话服务是否全部完成?1:未完成;0:完成
/**题目中所指的电话队列指的不可能是计算机用语中的队列,因为删除的不是总在开头*/
time_t *tel_que;//“电话队列”指针
void init()//初始化
{
int i;
system("clear");
printf("请输入客户服务人员的人数(建议输入5)\n");
scanf("%d", &customer_service_staff_num);
printf("请输入时间限制(建议输入20)(单位为分钟,此程序的1分钟为现实中的1秒)\n");
scanf("%ld", (long *)&time_limite);
printf("请输入电话到达的速率,指平均每分钟到达的电话数,取值范围(0,1](建议输入1)\n");
scanf("%lf", &telephone_rate);
printf("请输入平均服务时间(单位:分钟)(建议输入10)\n");
scanf("%d", &average_service_time);
tel_wait_que = queue_init(NULL);//电话等待队列初始化
queue_print(tel_wait_que, queuedata_print_phonedata);//打印当前电话服务状态信息
tel_que = (time_t *)malloc((sizeof(time_t)) * customer_service_staff_num);//初始化电话“队列”(实际为数组)的结构
for (i = 0; i < customer_service_staff_num; i++)//初始化“电话队列”的值为0。
{
tel_que[i] = 0;//0:表示当前电话无服务进行or电话服务正好结束
}
period_time = 1.0 / (double)telephone_rate;//初始化电话到达的周期
time(&rawtime);//获取当前时间
t = rawtime;//设置上次获取的时间
start_time = t;//设置服务开始时间
}
void check_new_tel()//检查是否有新的电话到达
{
if (0 == (rawtime % period_time) && (start_time + time_limite - t) > 0)//到达循环周期,收到电话。且必须满足条件“在时间限制之内”
{
queuedata qdata;
qdata.arrive_time = rawtime;//保存当前时间
qdata.service_time = (time_t)rand() % (average_service_time*2)+1;//分配随机服务时间
queue_push(tel_wait_que, qdata);//将新电话加入电话等待队列
phone_sum++;//电话数加一
}
}
void check_phone_service_finish()//检查电话服务是否完成,如果完成,则将电话从电话队列中删除,
{
//模拟服务将从队列中取出下一个电话(如果有)继续开始。
int i;
queuedata qdata;
phone_service_finished = 1;
for(i = 0; i < customer_service_staff_num; i++)//依次检查是否有电话空闲
{
if (tel_que[i] == 0)//客户服务人员空闲
{
if (queue_isempty(tel_wait_que) == 0)//有电话
{
queue_pop(tel_wait_que,&qdata);//从电话等待队列中取出第一个电话
wait_time_sum += (rawtime - qdata.arrive_time);//等待时间总和加上当前时间减去到达时间的差即当前电话等待时间
tel_que[i] = qdata.service_time;//倒计时赋初值 为服务时间
}
}
else//只要有一个客服服务人员没空闲 phone__service_finished 就是0
{
phone_service_finished = 0;//电话服务没全部完成
}
}
}
void phone_service_stat_print()//打印当前电话服务的状态信息
{
int i;
printf("各电话分机接听电话剩余时间\n");
for (i = 0; i < customer_service_staff_num; i++)
{
printf("%ld\t",(long)tel_que[i]);
}
}
void time_going()//时间流逝————将倒计时减一直到倒计时为0
{
int i;
for (i = 0; i < customer_service_staff_num; i++)
{
if (tel_que[i] > 0)
{
tel_que[i]--;
}
}
}
void service_circle()
{
while(((start_time + time_limite - t) > 0) || (phone_service_finished == 0))//如果没到时间限制 或者 电话服务没有全部完成
{
time( &rawtime );//获取当前时间
if (t != rawtime)//当前时间不等于上次获取时间 即表示进入下一秒了
{
system("clear");
// printf("累计耗时:%ld/截至时间长度:%ld\n", (long)(rawtime - start_time), (long)time_limite);
printf("开始时间:");
time_t_print(start_time);
printf("\n当前时间:");
time_t_print(rawtime);
printf("\n截止时间:");
time_t_print(start_time + time_limite);
// timeinfo = localtime ( &rawtime );
// printf ( "\007The current date/time is: %s", asctime (timeinfo) );//打印电脑时间信息 带格式
printf("\n预计处理的电话数为%d,等待总时间累计为%d分钟\n", phone_sum, wait_time_sum);
t = rawtime;//设置上次获取时间
srand( time(NULL) );
rand();
time_going();//时间流逝————倒计时减一
check_new_tel();//检查是否有新的电话到达
check_phone_service_finish();//检查电话服务是否完成,如果完成,则将电话从电话队列中删除,
//模拟服务将从队列中取出下一个电话(如果有)继续开始。
phone_service_stat_print();//打印当前电话服务的状态信息
printf("\n电话等待队列:\n");
queue_print(tel_wait_que, queuedata_print_phonedata);
}
}
}
void result_print()//打印结果
{
printf("\n全部处理完成。\n处理的电话数为%d,每个电话的平均等待时间为%f分钟\n", phone_sum, (float)wait_time_sum/(float)phone_sum);
}
int main(void)
{
init();//初始化
service_circle();//服务循环开始
result_print();//电话服务结果打印
return 0;
}
queue.c
#include "queue.h" queue queue_init(queue que) { if (que == NULL) { queue que= (queue)malloc(sizeof(Queue)); que->start = 0; que->end = 0; return que; } else { que = (queue)malloc(sizeof(Queue)); que->start = 0; que->end = 0; return que; }
} int queue_isempty(queue que) { if (que->start == que->end) { // printf("the queue is empty\n"); return 1; } else { return 0; } } int queue_isfull(queue que) { if ((que->end +1)%QUEUESIZE == que->start) { // printf("the queue is full!\n"); return 1; } else { return 0; } } int queue_push(queue que, queuedata data) { if (queue_isfull(que) == 1) { return -1; } que->qdata[que->end] = data; que->end++; if (que->end == 100) { que->end = 0; } return 0; } int queue_pop(queue que, queuedata *ch) { if (queue_isempty(que) == 1) { return -1; } *ch = que->qdata[que->start]; que->start++; if (que->start == 100) { que->start = 0; } return 0; } int queue_getstart(queue que, queuedata *ch) { if (queue_isempty(que) == 1) { return -1; } *ch = que->qdata[que->start]; return 0; } void queue_print(queue que, void (*print)(void *)) { int i; if (queue_isempty(que) == 1) { return; } if (que->start < que->end) { for (i = que->start; i < que->end; i++) { (*print)((void*)&que->qdata[i]); } } else { for (i = que->start; i < 100; i++) { (*print)((void*)&que->qdata[i]); } for (i = 0; i < que->end; i++) { (*print)((void*)&que->qdata[i]); } } printf("\n"); return ; } void time_t_print(time_t t) { struct tm *p; char *weekdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; p = localtime(&t); printf("%d/%d/%d ", (1900+p->tm_year), (1 + p->tm_mon), p->tm_mday); printf("%s %d:%d:%d", weekdays[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec); }
void queuedata_print_phonedata(void *qdata) { printf("到达时间:"); time_t_print(((queuedata*)qdata)->arrive_time); printf(" 随机分配服务时间:%ld分钟\n", ((queuedata*)qdata)->service_time); }
queue.h
#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED
#include #include #include #define QUEUESIZE 100
//typedef char queuedata;
typedef struct
{
time_t arrive_time;
time_t service_time;
}queuedata;
typedef struct QUEUE
{
queuedata qdata[100];
int start;
int end;
}Queue;
typedef Queue *queue;
queue queue_init(queue que);
int queue_isempty(queue que);
int queue_isfull(queue que);
int queue_push(queue que, queuedata data);
int queue_pop(queue que, queuedata *ch);
int queue_getstart(queue que, queuedata *ch);
void queue_print(queue que, void (*print)(void *));
void queuedata_print_phonedata(void *qdata);
#endif // QUEUE_H_INCLUDED