电梯模拟问题一、目的与要求1. 掌握线性结构的逻辑特点及存储实现;2. 根据选题,按规范化流程完成课程设计报告:⑴.提供需求分析。
(15分)⑵.列出概要设计。
(包括:抽象数据类型的描述;程序结构图或功能模块图)(20分)⑶.给出详细设计。
(包括:①存储结构的描述;②算法的详细设计,对复杂算法,最好画出其N-S流程图;③函数的调用关系图)(30分)⑷.进行调试分析(注:调试时遇到的问题及解决方法,程序的输出结果及对结果的分析)。
(15分)⑸. 整理设计总结。
(设计心得体会,以及其他总结信息等)(10分)⑹.附有程序清单(注:代码可具有适当注释,用来说明程序的功能、结构)。
(10分)二、设计步骤1、线性结构是有序数据元素的集合,存在着“一对一”的线性关系且只有一个首结点,一个尾结点,首结点只有后继没有前趋,尾结点只有前趋没有后继。
顺序表的存储结构包括顺序表和链表,顺序存储是指将线性表元素按照逻辑顺序依次存储在一组连续的地址单元中。
链式存储是通过结点中的链域将线性表中n个结点按其逻辑顺序链接在一起。
分为:单向链表,双向链表,循环链表。
2、(1)设计一个电梯模拟系统。
这是一个离散的模拟程序,因为电梯系统是乘客和电梯等“活动体”够成的集合,虽然他们彼此交互作用,但是他们的行为是基本独立的。
在离散的模拟中,一模拟时钟决定每个活动体的动作发生的时刻和顺序,系统在某个模拟瞬间处理有待完成的各种事情,然后把模拟时钟推进到某个动作预定要发生的下一个时刻。
可模拟某校五层教学楼的电梯系统,或者九层教学楼的电梯系统。
此程序的关键是模拟好电梯运行状态的转换与乘客进出的同步进行,需要一个函数判断电梯的运行状态,决定电梯的下一个运行状态如电梯的开门,关门,上升,下降,减速,加速等,也需要模拟时钟的函数来判断该运行哪个函数,也需要定义几个结构体存放结点信息。
(2)时钟函数:void DoTime(){//此函数用于模拟时钟while(1){if(Time>MaxTime)return;TestPeople();//两个始终都会被调用的函数Controler();struct Activity* p=activity.next;if(p==NULL){Time=MaxTime;}if(p&&Time>=p->time){//取出活动队头的,检测定时是否到了activity.next=p->next;p->fn();free(p);}Time++;}}其中activity是关键,它是一个链表在链表的头部是计时器时间最小的函数,根据模拟时钟判断是否调用这个函数以及删除这个节点。
以下是Activity的具体定义:typedef struct Activity{int time;void(*fn)(void);struct Activity* next;}Activity;定义说明:#ifndef _DIANTI_H_#define _DIANTI_H_#define GoingUp 1//匀速上升#define GoingDown 2//匀速下降#define SpeedUp 3//加速上升#define SpeedDown 4//加速下降#define SlowUp 5//减速上升准备停靠#define SlowDown 6//减速下降准备停靠#define Idle 7//空闲#define Stop 8//停止且已关门#define DoorOpen 9//停止且门已打开#define DoorOpening 10#define DoorCloseing 11#define CloseTest 40//电梯关门测试时间#define OverTime 300//电梯停候超时时间#define Accelerate 15//加速时间#define UpTime51//上升时间#define DownTime 61//下降时间#define UpDecelerate 14//上升减速#define DownDecelerate 23//下降减速#define DoorTime20//开门关门时间#define InOutTime25//进出电梯时间#define MaxTime 10000#define MaxFloor 5#define BaseFloor 1程序框图:开始Input()Dotime()结束(3)存储结构描述:此代码采用单链表的存储结构,结点存放起始楼层、目标楼层、容忍时间、下一个用户的到来时间等信息。
typedef struct Person{int Id;int OutFloor;int GiveupTime;struct Person* next;}Person;N-S流程图:Input():开始Person* p = (Person*)mallo c(sizeof(Person输入用户信息判断输入信息是否合p->Id=PersonId ++;Whil e (1) 否是否是 p->GiveupTime=giveuptime+Timep->next=NULL;p->OutFloor=ou tfloor;Dotime()N-S图:outfloor>infloCallUp[infloor]=1;CallDown[infloor]=1;是否AddQueue(infloor,p);AddAct(intertime,Input);结束开始While(1)Time>MareturnTestPeople();Controler();StructActivity*p=activity.next;p==NUTime=MaxTime;p&&Time>=p-activity.next=p->next;p->fn();Time++;结束函数调用关系图:运行结果截图:输入起始楼层和目标楼层,且保证在最大范围之内,再输入用户的等待时间和下一个用户的到达时间,电梯开始运行第一个用户走进电梯,电梯开始加速加速上升超过第二个用户的最长等待时间,用户二放弃了等待,电梯继续上升到达四层Main ()Input()Dotime()AddQueue(infloor ,p);AddAct(intertime,Input);TestPeople(); Controler();停止三、设计总结设计电梯模拟系统用了链表存储结构来存放节点信息,虽然做的不够全面,只是一个简单的模型,在熟悉链表的基础上做了多个链表的联合联合使用,新学到了时钟模拟函数,对我有很大帮助。
四、代码清单#include<stdio.h>#include<string.h>#define N 20typedef struct{char num[10];//车次号char startsa[10];//始发站char endsa[10];//终点站char date[10];//char startti[10];//发车时间char endti[10];//到达时间char type[10];//char price[10];//价格}Fight;typedef struct{Fight elem[N];int length;}Table;void Printf(Table &F,int n){int i;printf("请输入数据");for(i=1;i<=n;i++){printf("第%d个\n",i);printf("车次号为:");scanf("%s",&F.elem[i].num);printf("始发站为:");scanf("%s",&F.elem[i].startsa);printf("终点站为:");scanf("%s",&F.elem[i].endsa);printf("日期为:");scanf("%s",&F.elem[i].date);printf("出发时间为:");scanf("%s",&F.elem[i].startti);printf("到达时间为:");scanf("%s",&F.elem[i].endti);printf("类型为:");scanf("%s",&F.elem[i].type);printf("价格为:");scanf("%s",&F.elem[i].price);}}void Save(Table &F,int n)//将文件中的数据放入顺序表中{int i;n=0;FILE *fp;if((fp=fopen("train.txt","rb"))==NULL){printf("文件中没有数据,请输入信息!\n");}while((fp=fopen("train.txt","rb"))!=NULL){fscanf(fp,"%s%s%s%s%s%s%s%s",F.elem[i].num,F.elem[i].startsa,F.el em[i].endsa,F.elem[i].date,F.elem[i].startti,F.elem[i].endti,F.elem[i ].type,F.elem[i].price);n++;}F.length=n;fclose(fp);}void Read(Table &F,int n) //将数据保存在文件中{int i;FILE *fp;fp = fopen("train.txt", "wb");for(i=1;i<=n;i++){fprintf(fp,"%s%s%s%s%s%s%s%s",F.elem[i].num,F.elem[i].startsa,F.e lem[i].endsa,F.elem[i].date,F.elem[i].startti,F.elem[i].endti,F.elem[ i].type,F.elem[i].price);}F.length=n;fclose(fp);}void numsort(Table &F)//车次号排序{//冒泡排序int i,j;for(i=1;i<=F.length;i++){for(j=1;j<=F.length-i;j++){if(strcmp(F.elem[j].num,F.elem[j+1].num)==1){F.elem[0]=F.elem[j];F.elem[j]=F.elem[j+1];F.elem[j+1]=F.elem[0];}}}}void numsearch(Table &F,char key[10])//根据车次号查询{numsort(F);//折半查找int mid,low,high;low=1; high=F.length;while(low<=high){mid=(low+high)/2;if(strcmp(key,F.elem[mid].num)==0){printf("%s %s %s %s %s %s %s %s\n",F.elem[mid].num,F.elem[mid].st artsa,F.elem[mid].endsa,F.elem[mid].date,F.elem[mid].startti,F.elem[m id].endti,F.elem[mid].type,F.elem[mid].price);break;}else if(strcmp(key,F.elem[mid].num)==-1){high=mid-1;}elselow=mid+1;}}void startsasort(Table &F)//根据始发站排序{//冒泡排序int i,j;for(i=1;i<=F.length;i++){for(j=1;j<=F.length-i;j++){if(strcmp(F.elem[j].startsa,F.elem[j+1].startsa)==1){F.elem[0]=F.elem[j];F.elem[j]=F.elem[j+1];F.elem[j+1]=F.elem[0];}}}}void startsasearch(Table &F,char key[10])//始发站查找{startsasort(F);//折半查找int mid,low,high;low=1; high=F.length;while(low<=high){mid=(low+high)/2;if(strcmp(key,F.elem[mid].startsa)==0){printf("%s %s %s %s %s %s %s %s\n",F.elem[mid].num,F.elem[mid].st artsa,F.elem[mid].endsa,F.elem[mid].date,F.elem[mid].startti,F.elem[m id].endti,F.elem[mid].type,F.elem[mid].price);break;}else if(strcmp(key,F.elem[mid].startsa)==-1){high=mid-1;}elselow=mid+1;}}void endsasort(Table &F)//终点站排序{//冒泡排序int i,j;for(i=1;i<=F.length;i++){for(j=1;j<=F.length-i;j++){if(strcmp(F.elem[j].endsa,F.elem[j+1].endsa)==1){F.elem[0]=F.elem[j];F.elem[j]=F.elem[j+1];F.elem[j+1]=F.elem[0];}}}}void endsasearch(Table &F,char key[10])//终点站查找{endsasort(F);//折半查找int mid,low,high;low=1; high=F.length;while(low<=high){mid=(low+high)/2;if(strcmp(key,F.elem[mid].endsa)==0){printf("%s %s %s %s %s %s %s %s\n",F.elem[mid].num,F.elem[mid].st artsa,F.elem[mid].endsa,F.elem[mid].date,F.elem[mid].startti,F.elem[m id].endti,F.elem[mid].type,F.elem[mid].price);break;}else if(strcmp(key,F.elem[mid].endsa)==-1){high=mid-1;}elselow=mid+1;}}void starttisort(Table &F)//发车时间排序{//冒泡排序int i,j;for(i=1;i<=F.length;i++){for(j=1;j<=F.length-i;j++){if(strcmp(F.elem[j].startti,F.elem[j+1].startti)==1){F.elem[0]=F.elem[j];F.elem[j]=F.elem[j+1];F.elem[j+1]=F.elem[0];}}}}void starttisearch(Table &F,char key[10])//发车时间查询{starttisort(F);//折半查找int mid,low,high;low=1; high=F.length;while(low<=high){mid=(low+high)/2;if(strcmp(key,F.elem[mid].startti)==0){printf("%s %s %s %s %s %s %s %s\n",F.elem[mid].num,F.elem[mid].st artsa,F.elem[mid].endsa,F.elem[mid].date,F.elem[mid].startti,F.elem[m id].endti,F.elem[mid].type,F.elem[mid].price);break;}else if(strcmp(key,F.elem[mid].startti)==-1){high=mid-1;}elselow=mid+1;}}void endtisort(Table &F)//到达时间排序{//冒泡排序int i,j;for(i=1;i<=F.length;i++){for(j=1;j<=F.length-i;j++){if(strcmp(F.elem[j].endti,F.elem[j+1].endti)==1){F.elem[0]=F.elem[j];F.elem[j]=F.elem[j+1];F.elem[j+1]=F.elem[0];}}}}void endtisearch(Table &F,char key[10])//到达时间查找{endtisort(F);//折半查找int mid,low,high;low=1; high=F.length;while(low<=high){mid=(low+high)/2;if(strcmp(key,F.elem[mid].endti)==0){printf("%s %s %s %s %s %s %s %s\n",F.elem[mid].num,F.elem[mid].st artsa,F.elem[mid].endsa,F.elem[mid].date,F.elem[mid].startti,F.elem[m id].endti,F.elem[mid].type,F.elem[mid].price);break;}else if(strcmp(key,F.elem[mid].endti)==-1){high=mid-1;}elselow=mid+1;}}void Out(Table F)//输出所有列车信息{int i;printf("车次号\t始发站\t终点站\t日期\t出发时间\t到达时间\t类型\t价格\n");for(i=1;i<=F.length;i++){printf("\n");printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",F.elem[i].num,F.elem[i] .startsa,F.elem[i].endsa,F.elem[i].date,F.elem[i].startti,F.elem[i].e ndti,F.elem[i].type,F.elem[i].price);}}void Paixu(Table F){int x;printf("1.车次号排序\n");printf("2.始发站排序\n");printf("3.终点站排序(冒泡排序)\n");printf("4.发车时间排序\n");printf("5.到达时间排序\n");scanf("%d",&x);switch(x){case 1:numsort(F);Out(F);break;case 2:startsasort(F);Out(F);break;case 3:endsasort(F);Out(F);break;case 4:starttisort(F);Out(F);break;case 5:endtisort(F);Out(F);break;}}void Search(Table F){int x;char n[10];printf("1.车次号查询(折半查找)\n");printf("2.起点站查询\n");printf("3.到达站查询\n");printf("4.出发时间查询\n");printf("5.到达时间查询\n");scanf("%d",&x);switch(x){case 1:printf("输入车次号:");scanf("%s",n);numsearch(F,n);break;case 2:printf("输入起点站:");scanf("%s",n);startsasearch(F,n);break;case 3:printf("输入到达站:");scanf("%s",n);endsasearch(F,n);break;case 4:printf("输入出发时间站:");scanf("%s",n);starttisearch(F,n);break;case 5:printf("输入到达时间站:");scanf("%s",n);endtisearch(F,n);break;}}int main(){int n;int way;Table F;Save(F,n);printf("输入列车个数:");scanf("%d",&n);Printf(F,n);Read(F,n);Out(F);while(1){printf("1.排序2.查询");printf("\n请选择");scanf("%d",&way);switch(way){case 1:Paixu(F);break;case 2:Search(F);break;default:printf("请重新输入");}}return 0;}。