📄 新建 文本文档 (6).txt
字号:
模拟理发店经营例程
/*
作者:姚佳
版本:1.0
说明:1.以下程序实现了对理发店经营的模拟。只输出了每一个事件发生的时间,及事件
类型客户总逗留时间,平均逗留时间,总客户数,每一个级别理发师的收入。营
业时间改为宏定义,不同级别理发师的理发时间和收费我也写死在程序里了(理
发时间为理发师的级别乘5,收费为理发师的级别乘10),要完全按照题目要求还
需稍做修改(今天太迟了,还需要帮助再和我说一声,我愿意帮忙)。
2.以下程序用TC3调试通过
3.以下程序仅供参考
4.小女子用了一夜心血写以下代码
*/
/*--------------------以下是系统头问件 App.h------------------------------*/
#ifndef APP_H
#define APP_H
#define BOOL int
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define NULL 0
#define OVERFLOW 0
#define UNDERFLOW 0
typedef int Status;
typedef struct Customer{ //定义客户数据类型
int ArrivedTime;
int Duration;
int Level;
}Customer,QElemType;
typedef struct Event{ //定义事件数据类型
int OccurTime;
int EvenType;
}Event,ElemType;
#endif
/*--------------------------以下是队列头文件 Queue.h------------------------------*/
#include "App.h"
#define MAXQUEUESIZE 100
typedef struct SqQueue{ //队列数据类型定义
QElemType *base;
int front;
int rear;
}SqQueue;
Status InitQueue(SqQueue &Q); //队列初始化
int QueueLength(SqQueue Q); //返回队列长度
Status EnQueue(SqQueue &Q,QElemType e); //进队
Status DeQueue(SqQueue &Q,QElemType &e); //出队
Status GetQueue(SqQueue &Q,QElemType &e); //得到队列头元素
/*----------------------------以下是线性表头文件 LinkList.h---------------------------------*/
#include "App.h"
typedef struct LNode{ //线性表元素类型定义
ElemType data;
LNode* next;
}LNode,*Link,*Position;
typedef struct { //线性表类型定义
Link head,tail;
int len;
}LinkList;
Status InitList(LinkList &L); //初始化线性表
Status DestroyList(LinkList &L); //销毁线性表
Status ClearList(LinkList &L); //清空线性表
BOOL ListEmpty(LinkList L); //判断线性表是否为空
int ListLength(LinkList L); //返回线性表长度
int LocateElem(LinkList L,ElemType e,BOOL (*compaer)(ElemType,ElemType));//返回线性表中第一个和e符合关系compaer的元素
Status ListInsert(LinkList &L,int i,ElemType e);//插入e为线性表的第i个元素
Status ListDelete(LinkList &L,int i,ElemType &e);//删除线性表的第i个元素
Status InsertByCompare(LinkList &L,ElemType e,BOOL (*compare)(ElemType,ElemType)); //将e插入线性表中第一个和e符合关系compare的数据元素之前
/*--------------------------------以下是队列实现文件 Queue.cpp---------------------------*/
#include "Queue.h"
Status InitQueue(SqQueue &Q){ //队列初始化
Q.base=new QElemType[MAXQUEUESIZE];
if(!Q.base) return ERROR;
Q.front=Q.rear=0;
return OK;
}
int QueueLength(SqQueue Q){ //返回队列长度
return (Q.rear-Q.front+MAXQUEUESIZE)%MAXQUEUESIZE;
}
Status EnQueue(SqQueue &Q,QElemType e){ //进队
if((Q.rear+1)%MAXQUEUESIZE==Q.front) return OVERFLOW;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQUEUESIZE;
return OK;
}
Status DeQueue(SqQueue &Q,QElemType &e){ //出队
if(Q.front==Q.rear) return UNDERFLOW;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQUEUESIZE;
return OK;
}
Status GetQueue(SqQueue &Q,QElemType &e){ //得到队列头元素
if(Q.front==Q.rear) return UNDERFLOW;
e=Q.base[Q.front];
return OK;
}
/*-----------------------------------以下是线性表实现文件 LinkList.cpp------------------------------*/
#include "stdio.h"
#include "LinkList.h"
Status InitList(LinkList &L){
L.head=new LNode;
if(L.head==NULL) return ERROR;
L.head->next=NULL;
L.tail=L.head;
L.len=0;
return OK;
}
Status DestroyList(LinkList &L){
Position pNode;
while(L.head){
pNode=L.head;
L.head=L.head->next;
delete pNode;
}
return OK;
}
Status ClearList(LinkList &L){
if(L.head==NULL) return ERROR;
Position pNode;
pNode=L.head->next;
while(pNode){
L.head->next=pNode->next;
delete pNode;
pNode=L.head->next;
}
return OK;
}
BOOL ListEmpty(LinkList L){
return !L.len;
}
int ListLength(LinkList L){
return L.len;
}
int LocateElem(LinkList L,ElemType e,BOOL (*compare)(ElemType,ElemType)){
int i=1;
if(!L.head) return -1;
Position pNode;
pNode=L.head->next;
while(pNode&&!(*compare)(pNode->data,e)) {i++;pNode=pNode->next;}
if(!pNode) return 0;
else return i;
}
Status ListInsert(LinkList &L,int i,ElemType e){
int j=1;
Position pNode;
Link newNode;
if(i<1||i>L.len+1) return ERROR;
for(pNode=L.head;j<i;j++) pNode=pNode->next;
newNode=new LNode;
if(!newNode) return ERROR;
newNode->data=e;
newNode->next=pNode->next;
pNode->next=newNode;
L.len++;
return OK;
}
Status ListDelete(LinkList &L,int i,ElemType &e){
int j=1;
Position pNode,pPreNode;
if(i<1||i>L.len||!L.head) return ERROR;
for(pPreNode=L.head,pNode=L.head->next;j<i;j++,pPreNode=pNode,pNode=pNode->next);
pPreNode->next=pNode->next;
e=pNode->data;
L.len--;
delete pNode;
return OK;
}
Status InsertByCompare(LinkList &L,ElemType e,BOOL (*compare)(ElemType,ElemType)){
int index;
if(!L.head) return ERROR;
index=LocateElem(L,e,compare);
if(index==0) ListInsert(L,L.len+1,e);
else ListInsert(L,index,e);
return OK;
}
/*---------------------------------------以下是系统主控程序 BnakSimulation.cpp-------------------*/
#include "stdio.h"
#include "stdlib.h"
#include "LinkList.h"
#include "Queue.h"
#define CLOSETIME 480 //营业时间,可由用户输入
#define N 4 //N把理发椅,可由用户输入
typedef LinkList EventList; //事件表类型
typedef SqQueue CustomerQueue; //理发队列类型
Event ev; //当前事件
Customer customer; //客户记录
EventList eventlist; //事件表
CustomerQueue customerqueue[N]; //N个理发队列
int master[N]; //N个理发师的级别
int earning[3]={0,0,0}; //三个级别的收入
int TotalTime,CustomerNum; //总时间,总顾客数
BOOL compare(Event e1,Event e2){ //比较事件发生时间
return e1.OccurTime>e2.OccurTime;
}
int GetQueueOfMinLen(Customer cst){ //得到客户所要求级别理发师的最短队列
int i,min=100,j=0;
for(i=1;i<N;i++){
if(master[i-1]==cst.Level&&QueueLength(customerqueue[i])<min) {
min=QueueLength(customerqueue[i]);j=i;
}
}
return j;
}
void CustomerArrived(){ //处理客户到达事件
int nextarrivetime,level,index;
Event e;
CustomerNum++;
nextarrivetime=random(12); //随机产生下一个客户到达事件
level=random(3)+1; //随机产生到达客户的理发级别
printf("Customer Arrived at:%d;Level:%d\n",ev.OccurTime,level);
e.EvenType=0; //生成下一个客户到达事件
e.OccurTime=ev.OccurTime+nextarrivetime; //生成下一个客户到达事件
if(e.OccurTime<CLOSETIME)
InsertByCompare(eventlist,e,compare); //将客户到达事件插入事件表
customer.ArrivedTime=ev.OccurTime; //置客户到达时间
customer.Duration=level*5; //置客户理发所需时间
customer.Level=level;
index=GetQueueOfMinLen(customer); //得到最短对列序号
EnQueue(customerqueue[index],customer); //刚到的客户排队
if(QueueLength(customerqueue[index])==1){ //刚到的客户排在队头,生成一个客户离开事件
e.EvenType=index+1;
e.OccurTime=ev.OccurTime+customer.Duration;
InsertByCompare(eventlist,e,compare); //将离开事件插入线性表
}
}
void CustomerLeaved(){ //处理客户离开事件
int index;Event e;
printf("Customer leaved at:%d\n",ev.OccurTime);
index=ev.EvenType-1;
DeQueue(customerqueue[index],customer); //从队列中删除理完发的客户
TotalTime+=(ev.OccurTime-customer.ArrivedTime); //统计总逗留时间
earning[customer.Level-1]=earning[customer.Level-1]+customer.Level*10; //统计该级别的理发师收入
if(GetQueue(customerqueue[index],customer)){ //若该对列不为空,产生一个离开事件插入事件表
e.EvenType=index+1;
e.OccurTime=ev.OccurTime+customer.Duration;
InsertByCompare(eventlist,e,compare);
}
}
void OpenForDay(){ //系统初始化
int i=0;
InitList(eventlist); //初始化事件表
randomize(); //初始化随机数发生器
for(i=0;i<N;i++){
master[i]=i%3+1; //定义不同理发椅的级别,此处可改为由用户输入
InitQueue(customerqueue[i]); //初始化客户队列
}
}
void CloseForDay(){ //店铺关门
DestroyList(eventlist);
printf("CustomerNum:%d TotalTime:%d AverageTime:%d\n",CustomerNum,TotalTime,TotalTime/CustomerNum);
printf("level1 earning:%d,level2 earning:%d,level3 earning:%d",earning[0],earning[1],earning[2]);
}
void main(){
OpenForDay();
ev.EvenType=0; //产生第一个客户到达事件
ev.OccurTime=0;
InsertByCompare(eventlist,ev,compare);
while(!ListEmpty(eventlist)){
if(ListDelete(eventlist,1,ev)){ //取当前事件
if(ev.EvenType==0) CustomerArrived(); //若当前事件是客户到达事件,驱动执行客户到达事件
else CustomerLeaved(); //若当前事件是客户离开事件,驱动执行客户离开事件
}
}
CloseForDay();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -