文字描述
示意图
代码实现
//
// Created by Zhenjie Yu on 2019-04-13.
// #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h> #define DEBUG #define RED "\e[0;31m"
#define L_RED "\e[1;31m"
#define NONE "\e[0m" #ifdef DEBUG
#include <stdarg.h>
#define LOG(args...) _log_(__FILE__, __FUNCTION__, __LINE__, ##args);
static void _log_(const char *file, const char *function, int line, const char * format, ...)
{
char buf[] = {};
va_list list;
va_start(list, format);
// sprintf(buf, "[%s,%s,%d]", file, function, line);
vsprintf(buf+strlen(buf), format, list);
sprintf(buf+strlen(buf), "\n");
va_end(list);
printf(buf);
}
#else
#define LOG
#endif // DEBUG /////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
#define MAXQSIZE 100
typedef struct QElemType{
int ArrivalTime;
int Duration;
}QElemType; typedef struct{
QElemType *base;
int front;
int rear;
}SqQueue;
static int InitQueue(SqQueue *Q);
static int QueueLength(SqQueue Q);
static int EnQueue(SqQueue *Q, QElemType e);
static int DeQueue(SqQueue *Q, QElemType *e);
static int TraverseQueue(SqQueue Q);
static int QueueEmpty(SqQueue Q); //return 0:not empty; -1 empty
static int GetQueueHead(SqQueue Q, QElemType *e); /////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
#define LIST_INIT_SIZE 100
#define LIST_INCREMENT 10 typedef struct Event{
int OccurTime; //occur time of event.
int NType; //event type: 0 arrive; 1-4 queue 1-4 apart.
}Event, ElemType; typedef struct LinkList{
ElemType *elem;
int length;
int listsize;
}LinkList;
static int InitList(LinkList *L);
static int ListInsert(LinkList *L, ElemType e, int (*fun)(ElemType e1, ElemType e2));
static int ListDelete(LinkList *L, int locate, ElemType *e);
static int compare(ElemType e1, ElemType e2); // return -1(e1.ocurtime < e2.ocurtime), 0, 1
static int ListTraverse(LinkList L);
static int ListEmpty(LinkList L); //return 0:not empty; -1:empty /////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
typedef LinkList EventList;
EventList ev; //event table
Event en; //event
SqQueue q[+]; //four depart queue of customer
QElemType customer;
int TotalTime = ; //the total time of spend of all custmers
int CustomerNum = ; //the number of custmer
int CloseTime = ;
static int OpenForDay(){
TotalTime = ;
CustomerNum = ;
if(InitList(&ev)<){
LOG("error:init event list error!");
return -;
}
int i = ;
for(i=; i<=; i++){
if(InitQueue(&q[i]) < ){
LOG("error:init queue %d error!", i);
return -;
}
}
en.OccurTime = ;
en.NType = ;
if(ListInsert(&ev, en, compare)<){
LOG("error:insert event(%d,%d) error!", en.OccurTime, en.NType);
return -;
}
} static int Minimum(SqQueue qList[], int start, int end)
{
int i = ;
int ret = start;
for(i=start; i<=end; i++){
if(QueueLength(qList[i]) < QueueLength(qList[ret])){
ret = i;
}
}
return ret;
}
static int CustomerArrived(void){
srand((unsigned)time(NULL));
CustomerNum += ;
int durtime = rand()%+; //1-30
int intertime = rand()%+; //1-5
int t = en.OccurTime + intertime;
int i = ;
Event event;
QElemType qe;
if(t<CloseTime){
//Insert to event list
event.NType = ;
event.OccurTime = t;
if(ListInsert(&ev, event, compare)<){
LOG("error:fail when insert event(%d,%d)!", event.OccurTime, event.NType);
return -;
}
}
i = Minimum(q, , );
qe.ArrivalTime = en.OccurTime;
qe.Duration = durtime;
EnQueue(&q[i], qe);
if(QueueLength(q[i]) == ){
event.OccurTime = en.OccurTime+durtime;
event.NType = i;
if(ListInsert(&ev, event, compare)<){
LOG("error:fail insert (%d,%d) to List", event.OccurTime, event.NType);
return -;
}
}
return ;
} static int CustomerDeparture(void){
int i = en.NType;
Event event;
if(DeQueue(&q[i], &customer)<){
LOG("error:fail when delete from queue %d", i);
return -;
}
TotalTime += (en.OccurTime - customer.ArrivalTime);
if(!QueueEmpty(q[i])){
if(GetQueueHead(q[i], &customer)<){
LOG("error:fail when gethead from queue %d", i);
return -;
}
event.OccurTime = en.OccurTime+customer.Duration;
event.NType = i;
if(ListInsert(&ev, event, compare)<){
LOG("error:fail insert (%d,%d) to evenlist", event.OccurTime, event.NType);
return -;
}
}
return ;
} int main(int argc, char *argv[]){
LOG("利用队列实现银行业务模拟! 营业时间0 - %d", CloseTime);
int timer = ;
if(OpenForDay()<){
return -;
}
while(!ListEmpty(ev)){
timer += ;
if(ListDelete(&ev,,&en)<){
LOG("error:delete event from list error!");
break;
}
if(en.NType == ){
if(CustomerArrived()<){
LOG("error:handle new customer fail!");
break;
}
}else{
if(CustomerDeparture()<){
LOG("error:handle leave customer fail!");
break;
}
}
// if(timer % 20){
LOG("TotalTime=%d, CustomerNum=%d, timer=%d", TotalTime, CustomerNum, timer);
LOG("窗口 1");
TraverseQueue(q[]);
LOG("窗口 2");
TraverseQueue(q[]);
LOG("窗口 3");
TraverseQueue(q[]);
LOG("窗口 4");
TraverseQueue(q[]);
LOG("事件表");
ListTraverse(ev);
LOG("");
// } }
LOG("The Average Time is %f", (float)TotalTime/CustomerNum);
return ;
} /////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
static int InitQueue(SqQueue *Q)
{
Q->base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
if(Q->base == NULL){
return -;
}
Q->front = ;
Q->rear = ;
return ;
} static int QueueLength(SqQueue Q){
return (Q.rear-Q.front+MAXQSIZE) % MAXQSIZE;
} static int EnQueue(SqQueue *Q, QElemType e){
if((Q->rear++MAXQSIZE)%MAXQSIZE == Q->front){
LOG("error: queue full!");
return -;
}else{
Q->base[Q->rear] = e;
Q->rear = (Q->rear++ MAXQSIZE)%MAXQSIZE;
return ;
}
} static int DeQueue(SqQueue *Q, QElemType *e){
if(Q->front == Q->rear){
LOG("error: queue emopty!");
return -;
}else{
*e = Q->base[Q->front];
Q->front = (Q->front + + MAXQSIZE) % MAXQSIZE;
return ;
}
} static int TraverseQueue(SqQueue Q){
int i = Q.front;
do{
if(i == Q.rear){
break;
}
i = (i++MAXQSIZE) % MAXQSIZE;
}while();
return ;
}
//return 0:not empty; -1 empty
static int QueueEmpty(SqQueue Q){
if(Q.front == Q.rear){
return -;
}else{
return ;
}
} static int GetQueueHead(SqQueue Q, QElemType *e)
{
if(QueueEmpty(Q)){
return -;
}
(*e) = Q.base[Q.front];
return ;
} /////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
static int InitList(LinkList *L){
if(L==NULL){
return -;
}
if((L->elem=(ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType))) == NULL){
return -;
}
L->length = ;
L->listsize = LIST_INIT_SIZE;
return ;
} static int ListInsert(LinkList *L, ElemType e, int (*fun)(ElemType e1, ElemType e2)){
int i = ;
int j = ;
if(L->length == L->listsize){
//kuo rong
ElemType *newbase = NULL;
if((newbase=(ElemType*)realloc(L->elem, (L->listsize+LIST_INCREMENT)* sizeof(ElemType))) == NULL){
return -;
}
L->elem = newbase;
L->listsize += LIST_INCREMENT;
}
for(i=; i<L->length; i++){
if(fun(e, L->elem[i])<){
break;
}
}
for(j=L->length; j>=i; j--){
L->elem[j+] = L->elem[j];
}
L->elem[i] = e;
L->length += ;
return ;
} static int ListDelete(LinkList *L, int locate, ElemType *e){
if(locate< || locate>(L->length-) || L->length<){
return -;
}
(*e) = L->elem[locate];
int i = ;
for(i=locate+; i<L->length; i++){
L->elem[i-] = L->elem[i];
}
L->length -= ;
return ;
} static int compare(ElemType e1, ElemType e2){
if(e1.OccurTime < e2.OccurTime){
return -;
}else if(e1.OccurTime == e2.OccurTime){
return ;
}else{
return ;
}
} static int ListTraverse(LinkList L){
int i = ;
for(i=; i<L.length; i++){
LOG("序号%d=(发生时间%d, 事件类型%d)", i, L.elem[i].OccurTime, L.elem[i].NType);
}
} //return 0:not empty; -1:empty
static int ListEmpty(LinkList L){
if(L.length>){
return ;
}else{
return -;
}
}
利用队列实现银行业务模拟
代码运行
/home/lady/CLionProjects/untitled/cmake-build-debug/untitled
利用队列实现银行业务模拟! 营业时间0 - 50
TotalTime=0, CustomerNum=1, timer=1
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间4, 事件类型0)
序号1=(发生时间17, 事件类型1) TotalTime=0, CustomerNum=2, timer=2
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间8, 事件类型0)
序号1=(发生时间17, 事件类型1)
序号2=(发生时间21, 事件类型2) TotalTime=0, CustomerNum=3, timer=3
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间12, 事件类型0)
序号1=(发生时间17, 事件类型1)
序号2=(发生时间21, 事件类型2)
序号3=(发生时间25, 事件类型3) TotalTime=0, CustomerNum=4, timer=4
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间16, 事件类型0)
序号1=(发生时间17, 事件类型1)
序号2=(发生时间21, 事件类型2)
序号3=(发生时间25, 事件类型3)
序号4=(发生时间29, 事件类型4) TotalTime=0, CustomerNum=5, timer=5
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间17, 事件类型1)
序号1=(发生时间20, 事件类型0)
序号2=(发生时间21, 事件类型2)
序号3=(发生时间25, 事件类型3)
序号4=(发生时间29, 事件类型4) TotalTime=17, CustomerNum=5, timer=6
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间20, 事件类型0)
序号1=(发生时间21, 事件类型2)
序号2=(发生时间25, 事件类型3)
序号3=(发生时间29, 事件类型4)
序号4=(发生时间34, 事件类型1) TotalTime=17, CustomerNum=6, timer=7
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间21, 事件类型2)
序号1=(发生时间24, 事件类型0)
序号2=(发生时间25, 事件类型3)
序号3=(发生时间29, 事件类型4)
序号4=(发生时间34, 事件类型1) TotalTime=34, CustomerNum=6, timer=8
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间24, 事件类型0)
序号1=(发生时间25, 事件类型3)
序号2=(发生时间29, 事件类型4)
序号3=(发生时间34, 事件类型1) TotalTime=34, CustomerNum=7, timer=9
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间25, 事件类型3)
序号1=(发生时间28, 事件类型0)
序号2=(发生时间29, 事件类型4)
序号3=(发生时间34, 事件类型1)
序号4=(发生时间41, 事件类型2) TotalTime=51, CustomerNum=7, timer=10
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间28, 事件类型0)
序号1=(发生时间29, 事件类型4)
序号2=(发生时间34, 事件类型1)
序号3=(发生时间41, 事件类型2) TotalTime=51, CustomerNum=8, timer=11
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间29, 事件类型4)
序号1=(发生时间32, 事件类型0)
序号2=(发生时间34, 事件类型1)
序号3=(发生时间41, 事件类型2)
序号4=(发生时间45, 事件类型3) TotalTime=68, CustomerNum=8, timer=12
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间32, 事件类型0)
序号1=(发生时间34, 事件类型1)
序号2=(发生时间41, 事件类型2)
序号3=(发生时间45, 事件类型3) TotalTime=68, CustomerNum=9, timer=13
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间34, 事件类型1)
序号1=(发生时间36, 事件类型0)
序号2=(发生时间41, 事件类型2)
序号3=(发生时间45, 事件类型3)
序号4=(发生时间49, 事件类型4) TotalTime=86, CustomerNum=9, timer=14
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间36, 事件类型0)
序号1=(发生时间41, 事件类型2)
序号2=(发生时间45, 事件类型3)
序号3=(发生时间49, 事件类型4)
序号4=(发生时间51, 事件类型1) TotalTime=86, CustomerNum=10, timer=15
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间40, 事件类型0)
序号1=(发生时间41, 事件类型2)
序号2=(发生时间45, 事件类型3)
序号3=(发生时间49, 事件类型4)
序号4=(发生时间51, 事件类型1) TotalTime=86, CustomerNum=11, timer=16
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间41, 事件类型2)
序号1=(发生时间44, 事件类型0)
序号2=(发生时间45, 事件类型3)
序号3=(发生时间49, 事件类型4)
序号4=(发生时间51, 事件类型1) TotalTime=103, CustomerNum=11, timer=17
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间44, 事件类型0)
序号1=(发生时间45, 事件类型3)
序号2=(发生时间49, 事件类型4)
序号3=(发生时间51, 事件类型1)
序号4=(发生时间58, 事件类型2) TotalTime=103, CustomerNum=12, timer=18
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间45, 事件类型3)
序号1=(发生时间48, 事件类型0)
序号2=(发生时间49, 事件类型4)
序号3=(发生时间51, 事件类型1)
序号4=(发生时间58, 事件类型2) TotalTime=120, CustomerNum=12, timer=19
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间48, 事件类型0)
序号1=(发生时间49, 事件类型4)
序号2=(发生时间51, 事件类型1)
序号3=(发生时间58, 事件类型2) TotalTime=120, CustomerNum=13, timer=20
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间49, 事件类型4)
序号1=(发生时间51, 事件类型1)
序号2=(发生时间58, 事件类型2)
序号3=(发生时间65, 事件类型3) TotalTime=137, CustomerNum=13, timer=21
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间51, 事件类型1)
序号1=(发生时间58, 事件类型2)
序号2=(发生时间65, 事件类型3) TotalTime=168, CustomerNum=13, timer=22
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间58, 事件类型2)
序号1=(发生时间65, 事件类型3)
序号2=(发生时间68, 事件类型1) TotalTime=186, CustomerNum=13, timer=23
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间65, 事件类型3)
序号1=(发生时间68, 事件类型1)
序号2=(发生时间75, 事件类型2) TotalTime=203, CustomerNum=13, timer=24
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间68, 事件类型1)
序号1=(发生时间75, 事件类型2) TotalTime=235, CustomerNum=13, timer=25
窗口 1
窗口 2
窗口 3
窗口 4
事件表
序号0=(发生时间75, 事件类型2) TotalTime=266, CustomerNum=13, timer=26
窗口 1
窗口 2
窗口 3
窗口 4
事件表 The Average Time is 20.461538 Process finished with exit code 0
银行业务模拟运行结果