队列->队列的应用(银行业务模拟)
文字描述
示意图
代码实现
1 // 2 // Created by Zhenjie Yu on 2019-04-13. 3 // 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <unistd.h> 9 #include <time.h> 10 11 #define DEBUG 12 13 #define RED "\e[0;31m" 14 #define L_RED "\e[1;31m" 15 #define NONE "\e[0m" 16 17 #ifdef DEBUG 18 #include <stdarg.h> 19 #define LOG(args...) _log_(__FILE__, __FUNCTION__, __LINE__, ##args); 20 static void _log_(const char *file, const char *function, int line, const char * format, ...) 21 { 22 char buf[1024] = {0}; 23 va_list list; 24 va_start(list, format); 25 // sprintf(buf, "[%s,%s,%d]", file, function, line); 26 vsprintf(buf+strlen(buf), format, list); 27 sprintf(buf+strlen(buf), "\n"); 28 va_end(list); 29 printf(buf); 30 } 31 #else 32 #define LOG 33 #endif // DEBUG 34 35 ///////////////////////////////////////////////////////////////// 36 ///////////////////////////////////////////////////////////////// 37 ///////////////////////////////////////////////////////////////// 38 #define MAXQSIZE 100 39 typedef struct QElemType{ 40 int ArrivalTime; 41 int Duration; 42 }QElemType; 43 44 typedef struct{ 45 QElemType *base; 46 int front; 47 int rear; 48 }SqQueue; 49 static int InitQueue(SqQueue *Q); 50 static int QueueLength(SqQueue Q); 51 static int EnQueue(SqQueue *Q, QElemType e); 52 static int DeQueue(SqQueue *Q, QElemType *e); 53 static int TraverseQueue(SqQueue Q); 54 static int QueueEmpty(SqQueue Q); //return 0:not empty; -1 empty 55 static int GetQueueHead(SqQueue Q, QElemType *e); 56 57 58 ///////////////////////////////////////////////////////////////// 59 ///////////////////////////////////////////////////////////////// 60 ///////////////////////////////////////////////////////////////// 61 #define LIST_INIT_SIZE 100 62 #define LIST_INCREMENT 10 63 64 typedef struct Event{ 65 int OccurTime; //occur time of event. 66 int NType; //event type: 0 arrive; 1-4 queue 1-4 apart. 67 }Event, ElemType; 68 69 typedef struct LinkList{ 70 ElemType *elem; 71 int length; 72 int listsize; 73 }LinkList; 74 static int InitList(LinkList *L); 75 static int ListInsert(LinkList *L, ElemType e, int (*fun)(ElemType e1, ElemType e2)); 76 static int ListDelete(LinkList *L, int locate, ElemType *e); 77 static int compare(ElemType e1, ElemType e2); // return -1(e1.ocurtime < e2.ocurtime), 0, 1 78 static int ListTraverse(LinkList L); 79 static int ListEmpty(LinkList L); //return 0:not empty; -1:empty 80 81 ///////////////////////////////////////////////////////////////// 82 ///////////////////////////////////////////////////////////////// 83 ///////////////////////////////////////////////////////////////// 84 typedef LinkList EventList; 85 EventList ev; //event table 86 Event en; //event 87 SqQueue q[4+1]; //four depart queue of customer 88 QElemType customer; 89 int TotalTime = 0; //the total time of spend of all custmers 90 int CustomerNum = 0; //the number of custmer 91 int CloseTime = 50; 92 static int OpenForDay(){ 93 TotalTime = 0; 94 CustomerNum = 0; 95 if(InitList(&ev)<0){ 96 LOG("error:init event list error!"); 97 return -1; 98 } 99 int i = 1; 100 for(i=1; i<=4; i++){ 101 if(InitQueue(&q[i]) < 0){ 102 LOG("error:init queue %d error!", i); 103 return -1; 104 } 105 } 106 en.OccurTime = 0; 107 en.NType = 0; 108 if(ListInsert(&ev, en, compare)<0){ 109 LOG("error:insert event(%d,%d) error!", en.OccurTime, en.NType); 110 return -1; 111 } 112 } 113 114 static int Minimum(SqQueue qList[], int start, int end) 115 { 116 int i = 0; 117 int ret = start; 118 for(i=start; i<=end; i++){ 119 if(QueueLength(qList[i]) < QueueLength(qList[ret])){ 120 ret = i; 121 } 122 } 123 return ret; 124 } 125 static int CustomerArrived(void){ 126 srand((unsigned)time(NULL)); 127 CustomerNum += 1; 128 int durtime = rand()%29+1; //1-30 129 int intertime = rand()%4+1; //1-5 130 int t = en.OccurTime + intertime; 131 int i = 0; 132 Event event; 133 QElemType qe; 134 if(t<CloseTime){ 135 //Insert to event list 136 event.NType = 0; 137 event.OccurTime = t; 138 if(ListInsert(&ev, event, compare)<0){ 139 LOG("error:fail when insert event(%d,%d)!", event.OccurTime, event.NType); 140 return -1; 141 } 142 } 143 i = Minimum(q, 1, 4); 144 qe.ArrivalTime = en.OccurTime; 145 qe.Duration = durtime; 146 EnQueue(&q[i], qe); 147 if(QueueLength(q[i]) == 1){ 148 event.OccurTime = en.OccurTime+durtime; 149 event.NType = i; 150 if(ListInsert(&ev, event, compare)<0){ 151 LOG("error:fail insert (%d,%d) to List", event.OccurTime, event.NType); 152 return -1; 153 } 154 } 155 return 0; 156 } 157 158 static int CustomerDeparture(void){ 159 int i = en.NType; 160 Event event; 161 if(DeQueue(&q[i], &customer)<0){ 162 LOG("error:fail when delete from queue %d", i); 163 return -1; 164 } 165 TotalTime += (en.OccurTime - customer.ArrivalTime); 166 if(!QueueEmpty(q[i])){ 167 if(GetQueueHead(q[i], &customer)<0){ 168 LOG("error:fail when gethead from queue %d", i); 169 return -1; 170 } 171 event.OccurTime = en.OccurTime+customer.Duration; 172 event.NType = i; 173 if(ListInsert(&ev, event, compare)<0){ 174 LOG("error:fail insert (%d,%d) to evenlist", event.OccurTime, event.NType); 175 return -1; 176 } 177 } 178 return 0; 179 } 180 181 int main(int argc, char *argv[]){ 182 LOG("利用队列实现银行业务模拟! 营业时间0 - %d", CloseTime); 183 int timer = 0; 184 if(OpenForDay()<0){ 185 return -1; 186 } 187 while(!ListEmpty(ev)){ 188 timer += 1; 189 if(ListDelete(&ev,0,&en)<0){ 190 LOG("error:delete event from list error!"); 191 break; 192 } 193 if(en.NType == 0){ 194 if(CustomerArrived()<0){ 195 LOG("error:handle new customer fail!"); 196 break; 197 } 198 }else{ 199 if(CustomerDeparture()<0){ 200 LOG("error:handle leave customer fail!"); 201 break; 202 } 203 } 204 // if(timer % 20){ 205 LOG("TotalTime=%d, CustomerNum=%d, timer=%d", TotalTime, CustomerNum, timer); 206 LOG("窗口 1"); 207 TraverseQueue(q[1]); 208 LOG("窗口 2"); 209 TraverseQueue(q[2]); 210 LOG("窗口 3"); 211 TraverseQueue(q[3]); 212 LOG("窗口 4"); 213 TraverseQueue(q[4]); 214 LOG("事件表"); 215 ListTraverse(ev); 216 LOG(""); 217 // } 218 219 } 220 LOG("The Average Time is %f", (float)TotalTime/CustomerNum); 221 return 0; 222 } 223 224 225 226 227 ///////////////////////////////////////////////////////////////// 228 ///////////////////////////////////////////////////////////////// 229 ///////////////////////////////////////////////////////////////// 230 static int InitQueue(SqQueue *Q) 231 { 232 Q->base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType)); 233 if(Q->base == NULL){ 234 return -1; 235 } 236 Q->front = 0; 237 Q->rear = 0; 238 return 0; 239 } 240 241 static int QueueLength(SqQueue Q){ 242 return (Q.rear-Q.front+MAXQSIZE) % MAXQSIZE; 243 } 244 245 static int EnQueue(SqQueue *Q, QElemType e){ 246 if((Q->rear+1+MAXQSIZE)%MAXQSIZE == Q->front){ 247 LOG("error: queue full!"); 248 return -1; 249 }else{ 250 Q->base[Q->rear] = e; 251 Q->rear = (Q->rear+1+ MAXQSIZE)%MAXQSIZE; 252 return 0; 253 } 254 } 255 256 static int DeQueue(SqQueue *Q, QElemType *e){ 257 if(Q->front == Q->rear){ 258 LOG("error: queue emopty!"); 259 return -1; 260 }else{ 261 *e = Q->base[Q->front]; 262 Q->front = (Q->front + 1 + MAXQSIZE) % MAXQSIZE; 263 return 0; 264 } 265 } 266 267 static int TraverseQueue(SqQueue Q){ 268 int i = Q.front; 269 do{ 270 if(i == Q.rear){ 271 break; 272 } 273 i = (i+1+MAXQSIZE) % MAXQSIZE; 274 }while(1); 275 return 0; 276 } 277 //return 0:not empty; -1 empty 278 static int QueueEmpty(SqQueue Q){ 279 if(Q.front == Q.rear){ 280 return -1; 281 }else{ 282 return 0; 283 } 284 } 285 286 static int GetQueueHead(SqQueue Q, QElemType *e) 287 { 288 if(QueueEmpty(Q)){ 289 return -1; 290 } 291 (*e) = Q.base[Q.front]; 292 return 0; 293 } 294 295 296 297 ///////////////////////////////////////////////////////////////// 298 ///////////////////////////////////////////////////////////////// 299 ///////////////////////////////////////////////////////////////// 300 static int InitList(LinkList *L){ 301 if(L==NULL){ 302 return -1; 303 } 304 if((L->elem=(ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType))) == NULL){ 305 return -1; 306 } 307 L->length = 0; 308 L->listsize = LIST_INIT_SIZE; 309 return 0; 310 } 311 312 static int ListInsert(LinkList *L, ElemType e, int (*fun)(ElemType e1, ElemType e2)){ 313 int i = 0; 314 int j = 0; 315 if(L->length == L->listsize){ 316 //kuo rong 317 ElemType *newbase = NULL; 318 if((newbase=(ElemType*)realloc(L->elem, (L->listsize+LIST_INCREMENT)* sizeof(ElemType))) == NULL){ 319 return -1; 320 } 321 L->elem = newbase; 322 L->listsize += LIST_INCREMENT; 323 } 324 for(i=0; i<L->length; i++){ 325 if(fun(e, L->elem[i])<0){ 326 break; 327 } 328 } 329 for(j=L->length; j>=i; j--){ 330 L->elem[j+1] = L->elem[j]; 331 } 332 L->elem[i] = e; 333 L->length += 1; 334 return 0; 335 } 336 337 static int ListDelete(LinkList *L, int locate, ElemType *e){ 338 if(locate<0 || locate>(L->length-1) || L->length<1){ 339 return -1; 340 } 341 (*e) = L->elem[locate]; 342 int i = 0; 343 for(i=locate+1; i<L->length; i++){ 344 L->elem[i-1] = L->elem[i]; 345 } 346 L->length -= 1; 347 return 0; 348 } 349 350 static int compare(ElemType e1, ElemType e2){ 351 if(e1.OccurTime < e2.OccurTime){ 352 return -1; 353 }else if(e1.OccurTime == e2.OccurTime){ 354 return 0; 355 }else{ 356 return 1; 357 } 358 } 359 360 static int ListTraverse(LinkList L){ 361 int i = 0; 362 for(i=0; i<L.length; i++){ 363 LOG("序号%d=(发生时间%d, 事件类型%d)", i, L.elem[i].OccurTime, L.elem[i].NType); 364 } 365 } 366 367 //return 0:not empty; -1:empty 368 static int ListEmpty(LinkList L){ 369 if(L.length>0){ 370 return 0; 371 }else{ 372 return -1; 373 } 374 }
代码运行
1 /home/lady/CLionProjects/untitled/cmake-build-debug/untitled 2 利用队列实现银行业务模拟! 营业时间0 - 50 3 TotalTime=0, CustomerNum=1, timer=1 4 窗口 1 5 窗口 2 6 窗口 3 7 窗口 4 8 事件表 9 序号0=(发生时间4, 事件类型0) 10 序号1=(发生时间17, 事件类型1) 11 12 TotalTime=0, CustomerNum=2, timer=2 13 窗口 1 14 窗口 2 15 窗口 3 16 窗口 4 17 事件表 18 序号0=(发生时间8, 事件类型0) 19 序号1=(发生时间17, 事件类型1) 20 序号2=(发生时间21, 事件类型2) 21 22 TotalTime=0, CustomerNum=3, timer=3 23 窗口 1 24 窗口 2 25 窗口 3 26 窗口 4 27 事件表 28 序号0=(发生时间12, 事件类型0) 29 序号1=(发生时间17, 事件类型1) 30 序号2=(发生时间21, 事件类型2) 31 序号3=(发生时间25, 事件类型3) 32 33 TotalTime=0, CustomerNum=4, timer=4 34 窗口 1 35 窗口 2 36 窗口 3 37 窗口 4 38 事件表 39 序号0=(发生时间16, 事件类型0) 40 序号1=(发生时间17, 事件类型1) 41 序号2=(发生时间21, 事件类型2) 42 序号3=(发生时间25, 事件类型3) 43 序号4=(发生时间29, 事件类型4) 44 45 TotalTime=0, CustomerNum=5, timer=5 46 窗口 1 47 窗口 2 48 窗口 3 49 窗口 4 50 事件表 51 序号0=(发生时间17, 事件类型1) 52 序号1=(发生时间20, 事件类型0) 53 序号2=(发生时间21, 事件类型2) 54 序号3=(发生时间25, 事件类型3) 55 序号4=(发生时间29, 事件类型4) 56 57 TotalTime=17, CustomerNum=5, timer=6 58 窗口 1 59 窗口 2 60 窗口 3 61 窗口 4 62 事件表 63 序号0=(发生时间20, 事件类型0) 64 序号1=(发生时间21, 事件类型2) 65 序号2=(发生时间25, 事件类型3) 66 序号3=(发生时间29, 事件类型4) 67 序号4=(发生时间34, 事件类型1) 68 69 TotalTime=17, CustomerNum=6, timer=7 70 窗口 1 71 窗口 2 72 窗口 3 73 窗口 4 74 事件表 75 序号0=(发生时间21, 事件类型2) 76 序号1=(发生时间24, 事件类型0) 77 序号2=(发生时间25, 事件类型3) 78 序号3=(发生时间29, 事件类型4) 79 序号4=(发生时间34, 事件类型1) 80 81 TotalTime=34, CustomerNum=6, timer=8 82 窗口 1 83 窗口 2 84 窗口 3 85 窗口 4 86 事件表 87 序号0=(发生时间24, 事件类型0) 88 序号1=(发生时间25, 事件类型3) 89 序号2=(发生时间29, 事件类型4) 90 序号3=(发生时间34, 事件类型1) 91 92 TotalTime=34, CustomerNum=7, timer=9 93 窗口 1 94 窗口 2 95 窗口 3 96 窗口 4 97 事件表 98 序号0=(发生时间25, 事件类型3) 99 序号1=(发生时间28, 事件类型0) 100 序号2=(发生时间29, 事件类型4) 101 序号3=(发生时间34, 事件类型1) 102 序号4=(发生时间41, 事件类型2) 103 104 TotalTime=51, CustomerNum=7, timer=10 105 窗口 1 106 窗口 2 107 窗口 3 108 窗口 4 109 事件表 110 序号0=(发生时间28, 事件类型0) 111 序号1=(发生时间29, 事件类型4) 112 序号2=(发生时间34, 事件类型1) 113 序号3=(发生时间41, 事件类型2) 114 115 TotalTime=51, CustomerNum=8, timer=11 116 窗口 1 117 窗口 2 118 窗口 3 119 窗口 4 120 事件表 121 序号0=(发生时间29, 事件类型4) 122 序号1=(发生时间32, 事件类型0) 123 序号2=(发生时间34, 事件类型1) 124 序号3=(发生时间41, 事件类型2) 125 序号4=(发生时间45, 事件类型3) 126 127 TotalTime=68, CustomerNum=8, timer=12 128 窗口 1 129 窗口 2 130 窗口 3 131 窗口 4 132 事件表 133 序号0=(发生时间32, 事件类型0) 134 序号1=(发生时间34, 事件类型1) 135 序号2=(发生时间41, 事件类型2) 136 序号3=(发生时间45, 事件类型3) 137 138 TotalTime=68, CustomerNum=9, timer=13 139 窗口 1 140 窗口 2 141 窗口 3 142 窗口 4 143 事件表 144 序号0=(发生时间34, 事件类型1) 145 序号1=(发生时间36, 事件类型0) 146 序号2=(发生时间41, 事件类型2) 147 序号3=(发生时间45, 事件类型3) 148 序号4=(发生时间49, 事件类型4) 149 150 TotalTime=86, CustomerNum=9, timer=14 151 窗口 1 152 窗口 2 153 窗口 3 154 窗口 4 155 事件表 156 序号0=(发生时间36, 事件类型0) 157 序号1=(发生时间41, 事件类型2) 158 序号2=(发生时间45, 事件类型3) 159 序号3=(发生时间49, 事件类型4) 160 序号4=(发生时间51, 事件类型1) 161 162 TotalTime=86, CustomerNum=10, timer=15 163 窗口 1 164 窗口 2 165 窗口 3 166 窗口 4 167 事件表 168 序号0=(发生时间40, 事件类型0) 169 序号1=(发生时间41, 事件类型2) 170 序号2=(发生时间45, 事件类型3) 171 序号3=(发生时间49, 事件类型4) 172 序号4=(发生时间51, 事件类型1) 173 174 TotalTime=86, CustomerNum=11, timer=16 175 窗口 1 176 窗口 2 177 窗口 3 178 窗口 4 179 事件表 180 序号0=(发生时间41, 事件类型2) 181 序号1=(发生时间44, 事件类型0) 182 序号2=(发生时间45, 事件类型3) 183 序号3=(发生时间49, 事件类型4) 184 序号4=(发生时间51, 事件类型1) 185 186 TotalTime=103, CustomerNum=11, timer=17 187 窗口 1 188 窗口 2 189 窗口 3 190 窗口 4 191 事件表 192 序号0=(发生时间44, 事件类型0) 193 序号1=(发生时间45, 事件类型3) 194 序号2=(发生时间49, 事件类型4) 195 序号3=(发生时间51, 事件类型1) 196 序号4=(发生时间58, 事件类型2) 197 198 TotalTime=103, CustomerNum=12, timer=18 199 窗口 1 200 窗口 2 201 窗口 3 202 窗口 4 203 事件表 204 序号0=(发生时间45, 事件类型3) 205 序号1=(发生时间48, 事件类型0) 206 序号2=(发生时间49, 事件类型4) 207 序号3=(发生时间51, 事件类型1) 208 序号4=(发生时间58, 事件类型2) 209 210 TotalTime=120, CustomerNum=12, timer=19 211 窗口 1 212 窗口 2 213 窗口 3 214 窗口 4 215 事件表 216 序号0=(发生时间48, 事件类型0) 217 序号1=(发生时间49, 事件类型4) 218 序号2=(发生时间51, 事件类型1) 219 序号3=(发生时间58, 事件类型2) 220 221 TotalTime=120, CustomerNum=13, timer=20 222 窗口 1 223 窗口 2 224 窗口 3 225 窗口 4 226 事件表 227 序号0=(发生时间49, 事件类型4) 228 序号1=(发生时间51, 事件类型1) 229 序号2=(发生时间58, 事件类型2) 230 序号3=(发生时间65, 事件类型3) 231 232 TotalTime=137, CustomerNum=13, timer=21 233 窗口 1 234 窗口 2 235 窗口 3 236 窗口 4 237 事件表 238 序号0=(发生时间51, 事件类型1) 239 序号1=(发生时间58, 事件类型2) 240 序号2=(发生时间65, 事件类型3) 241 242 TotalTime=168, CustomerNum=13, timer=22 243 窗口 1 244 窗口 2 245 窗口 3 246 窗口 4 247 事件表 248 序号0=(发生时间58, 事件类型2) 249 序号1=(发生时间65, 事件类型3) 250 序号2=(发生时间68, 事件类型1) 251 252 TotalTime=186, CustomerNum=13, timer=23 253 窗口 1 254 窗口 2 255 窗口 3 256 窗口 4 257 事件表 258 序号0=(发生时间65, 事件类型3) 259 序号1=(发生时间68, 事件类型1) 260 序号2=(发生时间75, 事件类型2) 261 262 TotalTime=203, CustomerNum=13, timer=24 263 窗口 1 264 窗口 2 265 窗口 3 266 窗口 4 267 事件表 268 序号0=(发生时间68, 事件类型1) 269 序号1=(发生时间75, 事件类型2) 270 271 TotalTime=235, CustomerNum=13, timer=25 272 窗口 1 273 窗口 2 274 窗口 3 275 窗口 4 276 事件表 277 序号0=(发生时间75, 事件类型2) 278 279 TotalTime=266, CustomerNum=13, timer=26 280 窗口 1 281 窗口 2 282 窗口 3 283 窗口 4 284 事件表 285 286 The Average Time is 20.461538 287 288 Process finished with exit code 0