資源下載(包含所有代碼、MakeFile、以及一份簡單描述分析思路和流程圖的WORD文檔):http://download.csdn.net/detail/htianlong/4443226
/*************************************************************題目:電話客戶服務類比 1、 問題描述一個類比時鐘提供電話中服務的時間(以分鐘計),然後這個時鐘將迴圈地自增1(分鐘),直到到達指定的時間為止。在時鐘的每個“時刻”,就會執行一次檢查來看看當前電話的服務是否已經完成,如果是,這個電話從電話隊列中刪除,類比服務將從隊列中取出下一個電話(如果有)繼續開始。同時還需要執行一個檢查來判斷是否有一個新的電話到達,如果有將其到達的時間記錄下來,並為其產生一個隨機服務時間,這個服務時間也被記錄下來,然後將這個電話放入電話隊列中,當客戶服務人員空閑時,按照先來先服務的方式處理這個隊列。當時鐘到達指定時間時,不會再接聽新電話,但是服務將繼續,直到隊列中所有電話得到處理為止。 2、 要求 (1) 程式需要處理的初始資料包括:客戶服務人員的人數、時間限制,電話到達的速率,平均服務時間。 (2) 程式產生的結果包括:處理的電話數,每個電話的平均等待時間運行環境:LinuxLinux下調試通過。*************************************************************/#include <stdio.h>#include <time.h>#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("開始時間:"); time_t_print(start_time); printf("\n目前時間:"); time_t_print(rawtime); printf("\n截止時間:"); time_t_print(start_time + time_limite); 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.h:
#ifndef QUEUE_H_INCLUDED#define QUEUE_H_INCLUDED#include <stdio.h>#include <malloc.h>#include <time.h>#define QUEUESIZE 100typedef 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
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);}