电梯模拟
case Down: E.status=Moving;E.Count=DownTime+Accelerate;return GoingDown;
case Stop:if(E.status!=Waiting) {E.status=Waiting;E.Count=OverTime;}
};//switch
Status InitStack(ClientStack &S);//构造一个空栈
Status DestroyStack(ClientStack &S);//销毁栈S
Status ClearStack(ClientStack &S);//把S置为空
Status StackEmpty(ClientStack S);//若栈S为空,则返回TRUE,否则返回FALSE
#include <time.h>
2.各函数说明如下:
#define DownDecelerate 23//下降减速
#define DoorTime20//开门关门时间
#define InOutTime25//进出电梯时间
#define Maxfloor4//最高层
#define Minfloor0//最低层
E.Stage=Up;return TRUE;
}
return FALSE;
}
Status EleOpenDoor(Elevator &E) {
//判断电梯是否要开门
if(E.CallCar[E.floor]||E.CallDown[E.floor]&&E.Stage==Down||E.CallUp[E.floor]&&E.Stage==Up)
delete p;
return OK;
}
Status QueueEmpty(WQueue Q) {
//判断队列是否为空
if(Q.front==Q.rear) return TRUE;
elsereturn FALSE;
}
Status QDelNode(WQueue &Q,QueuePtr p) {
//删除队列中p指向的结点的下一个结点
//转到开门状态
E.status=Opening;E.Count=DoorTime;
break;
};//switch
return None;
}//ElevatorRun
//单链队列——队列的链式存储结构
typedef Client *QElemType;
//等候队列
typedef struct QNode {
return DoorClosed;
case Waiting:
//不在第一层且超出所规定的停候时间,电梯向第一层移动
if(E.Count==0) {
if(E.floor!=1) E.CallCar[1]=1;
}
else E.Count--;
//如果有人可以进入,则开门
if(EleOpenDoor(E)) {
QElemTypedata;
struct QNode*next;
}QNode,*QueuePtr;
typedef struct {
QueuePtrfront;//队头指针
QueuePtrrear;//队尾指针
}WQueue;
//等待队列的基本操作
Status InitQueue(WQueue &Q) {
TotalTime+=Time-CInTime(*(p->next->data));
QueuePtr q;
if(p==NULL||p->next==NULL) return ERROR;
q=p->next;
p->next=q->next;
if(p->next==NULL) Q.rear=p;
DestoryClient(q->data);
delete q;
return OK;
}
Status CGiveUp(WQueue &Q,int floor) {
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;
//否则返回ERROR
QueuePtr p;
if(Q.front==Q.rear) return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p) Q.rear=Q.front;
//判断电梯动作
int Above,Below;
Above=RequireAbove(E);
Below=RequireBelow(E);
//无请求则停止
if(Above==0&&Below==0) return Stop;
//有请求则按请求移动
else {
if(E.Stage==Up) {
if(Above!=0) return Up;
二.设计
1.设计思想
(1)数据结构设计
构建一个栈用以表示乘客,用等待队列表示电梯外等待的乘客
(2)算法设计
1.乘客类型反映乘客的所有属性
2乘客栈类型,电梯内的乘客用乘客栈表示,去不同楼层的乘客放在不同的栈中。
3.等候队列类型,在电梯外等待的乘客用等待队列表示。每层各有两个等待队列,分别为上楼队列和下楼队列。
void PrintStack(ClientStack &S);//输出栈
3.详细设计
基本数据结构为:
Status EleAchieved(Elevator &E) {
//判断电梯是否要停于当前层
if(E.CallCar[E.floor]) return TRUE;
if(E.Stage==Up&&E.CallUp[E.floor]||E.Stage==Down&&E.CallDown[E.floor])
return TRUE;
if(E.status==Waiting) {
if(E.CallDown[E.floor]) {E.Stage=Down;return TRUE;}
if(E.CallUp[E.floor]) {E.Stage=Up;return TRUE;}
}
return FALSE;
}
EleStage EleDecide(Elevator &E) {
E.Stage==Up&&!E.CallCar[E.floor]&&!E.CallUp[E.floor]) {//无人进出,关门
E.status=Closing;E.Count=DoorTime;
}//if
break;
case Closing:
//完成关门则转入Closed状态
E.status=Closed;
//删除放弃等待的乘客
QueuePtr p;
p=Q.front;
if(p->next!=NULL)
if(p->next->data->GivepuTime==0&&floor!=p->next->data->Infloor) {
PrintClientInfo(*(p->next->data),GiveUp);
模拟时钟从0开始,时间单位为0.1秒。人和电梯的各种动作均要消耗一定的时间单位(简记为t),比如:有人进出时,电梯每隔40t测试一次,若无人进出,则关门;关门和开门各需要20t;每个人进出电梯均需要25t;如果电梯在某层静止时间超过300t,则驶回1层侯命。
要求:
按时序显示系统状态的变化过程,即发生的全部人和电梯的动作序列。
return TRUE;
if(E.Stage==Up&&E.CallDown[E.floor]&&!RequireAbove(E)) {
E.Stage=Down;return TRUE;
}
if(E.Stage==Down&&E.CallUp[E.floor]&&!RequireBelow(E)) {
long Time=0;//时钟
long MaxTime;//系统运行最长时间
int InOutCount=0;//用于进出计时
int InterTime=0;//下一乘客进入系统的时间
int ID=0;//乘客编号
int GiveUpNumber=0;//乘客放弃的数目
int TotalTime=0;//总共等待时间
//构造一个空队列Q
Q.front=Q.rear=new QNode;
if(!Q.front) return OVERFLOW;//分配存储失败
Q.front->next=NULL;
Q.front->data=NULL;
return OK;
}
Status DestroyQueue(WQueue &Q) {
//销毁队列Q
while(Q.front) {
Q.rear=Q.front->next;
if(Q.front->data) DestoryClient(Q.front->data);
delete Q.front;
Q.front=Q.rear;
}
return OK;
}
Status EnQueue(WQueue &Q,QElemType e) {
else {
E.Stage=Down;return Down;