教学计划编排问题.docx

上传人:b****5 文档编号:6221117 上传时间:2023-01-04 格式:DOCX 页数:20 大小:231.53KB
下载 相关 举报
教学计划编排问题.docx_第1页
第1页 / 共20页
教学计划编排问题.docx_第2页
第2页 / 共20页
教学计划编排问题.docx_第3页
第3页 / 共20页
教学计划编排问题.docx_第4页
第4页 / 共20页
教学计划编排问题.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

教学计划编排问题.docx

《教学计划编排问题.docx》由会员分享,可在线阅读,更多相关《教学计划编排问题.docx(20页珍藏版)》请在冰豆网上搜索。

教学计划编排问题.docx

教学计划编排问题

姓名蒲茜

学号1705990111

班级计算机1701

年级2017级

指导教师杨新安

西安财经学院信息学院

《数据结构》课程设计报告

课程设计名称教学计划编排问题实验室完成日期2018.12.1

一、    需求分析

【问题描述】

大学的每个专业都要制订教学计划。

假设任何专业都有固定的学习年限,每学年含两学期,每学期的时间长度和学分上限均相等。

每个专业开设的课程都是确定的,而且课程在开设时

间的安排必须满足先修关系。

每门课程有哪些先修课程是确定的,可以有任意多门,也可以没有。

每门课恰好占一个学期。

试在这样的前提下设计一个教学计划编制程序。

【基本要求】

(1)输入参数包括:

学期总数,一学期的学分上限,每门课的课程号(固定占3位的字母数字串)、学分和直接先修课的课程号。

(2)允许用户指定下列两种编排策略之一:

一是使学生在各学期中的学习负担尽量均匀;二是使课程尽可能地集中在前几个学期中。

(3)若根据给定的条件问题无解,则报告适当的信息;否则,将教学计划输出到用户指定的文件中。

计划的表格格式自行设计。

【测试数据】

学期总数:

8;

学分上限:

10;

该专业共开设课数:

16

课程号:

C01C02C03C04C05C06C07C08C09C10C11C12C13C14C15C16

学分顺序:

2 3 4 3 2 3 4 4 4 5 442323

先修关系如下表:

C01

C02C04C03C12

C02

C03

C03

C05C07C08

C04

C05

C05

C07

C06

C08

C07

C08

C09

C10C11C12

C10

C12

C11

C06

C12

C13

C11

C14

C13

C15

C13C11

C16

C15

 

【实现提示】

可设学期总数不超过10,课程总数不超过60。

如果输入的先修课程号不在该专业开设的课程序列中,则作为错误处理。

应建立内部课程号与课程号之间的对应关系。

二、    概要设计

抽象数据类型描述:

typedefstructArcNode{

}ArcNode;表节点(弧结构);

typedefstruct{

}VNode,AdjList[MAX_VERTEX_NUM];头结点;

typedefstruct{

}ALGraph;图结构;

intLocateVex(ALGraphG,VertexTypeu)

操作结果:

 若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 ;

StatusCreateGraph(ALGraph&G)采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造种图);

voidDisplay(ALGraphG)输出图的邻接矩阵G ;

voidFindInDegree(ALGraphG,intindegree[])求顶点的入度;

typedefstructSqStack{

}SqStack;顺序栈;

StatusInitStack(SqStack*S)构造一个空栈S;

voidClearStack(SqStack*S)清空栈的操作;

StatusStackEmpty(SqStackS)若栈S为空栈,则返回TRUE,否则返回FALSE ;

StatusPop(SqStack*S,SElemType*e)若栈不空,则删除S的栈顶元素,用e返回其值,并返回O:

否则返回ERROR ;

StatusPush(SqStack*S,SElemTypee)插入元素e为新的栈顶元素;

Statuszxf(ALGraphG)求大学所有课程总学分;

StatusTopologicalSort(ALGraphG)程序的核心函数:

有向图G采用邻接表存储结构,若G无回路,则按用户选择的方案输出G的顶点的一个拓扑序列并返回OK,否则返回ERROR;

intmain()主函数;

功能模块图:

 

三、详细设计

存储结构及宏定义:

#defineMAX_VERTEX_NUM100

#defineSTACK_INIT_SIZE10

#defineSTACKINCREMENT2

图的邻接表存储:

typedefstructArcNode{//弧结构;

intadjvex;//该弧所指向的顶点的位置;

structArcNode*nextarc;//指向下一条弧的指针;

}ArcNode;//表结点;

typedefstruct{

AdjListvertices,vertices2;//分别存课程名和学分;

intvexnum,arcnum;

intkind;

}ALGraph;

栈的顺序存储:

typedefstructSqStack{

SElemType*base;

SElemType*top;

intstacksize;

}SqStack;

算法设计:

//对各顶点求入度indegree

voidFindInDegree(ALGraphG,intindegree[]){

inti;

ArcNode*p;

for(i=0;i

indegree[i]=0;

for(i=0;i

p=G.vertices[i].firstarc;

while(p){

indegree[p->adjvex]++;

p=p->nextarc;

}

}

}

//出栈

StatusPop(SqStack*S,SElemType*e){

if((*S).top==(*S).base)

returnERROR;

*e=*--(*S).top;

returnOK;

}

//入栈

StatusPush(SqStack*S,SElemTypee){

if((*S).top-(*S).base>=(*S).stacksize){

(*S).base=(SElemType*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));

if(!

(*S).base)

exit(OVERFLOW);

(*S).top=(*S).base+(*S).stacksize;

(*S).stacksize+=STACKINCREMENT;

}

*((*S).top)++=e;

returnOK;

}

//构造图G

StatusCreateGraph(ALGraph&G){

inti,j,k;

VertexTypev1,v2;//顶点信息;

ArcNode*p;//指向第一条依附某顶点的弧的指针;

printf("请输入教学计划的课程数:

");

scanf("%d",&G.vexnum);

printf("请输入课程先修关系数(弧的数目):

");

scanf("%d",&G.arcnum);

printf("请输入%d个课程的代表值(如:

c01):

\n",G.vexnum);

for(i=0;i

scanf("%s",G.vertices[i].data);

G.vertices[i].firstarc=NULL;

}

printf("请输入%d个课程的学分值:

\n",(G).vexnum);

for(i=0;i

scanf("%s",G.vertices2[i].data);

}

printf("请顺序输入每条弧的弧尾和弧头(以空格作为间隔):

\n");

for(k=0;k

scanf("%s%s",v1,v2);

i=LocateVex(G,v1);

j=LocateVex(G,v2);

p=(ArcNode*)malloc(sizeof(ArcNode));//新建一个节点;

p->adjvex=j;

p->info=NULL;

p->nextarc=G.vertices[i].firstarc;

G.vertices[i].firstarc=p;

}

returnOK;

}

函数调用关系图:

 

四、 调试分析

遇到的最大困难应该是算法的设计,因为平时学的比较死板,遇到这种设计作业就摸不着头脑。

刚开始会就不停的复习栈,图,拓扑排序。

但还是没有思路,翻阅了一些书籍,并在网上搜索了有关拓扑排序的算的大体思路,经过好几天的不断修改和调试,才完成了这个算法。

设计的过程中还是存在很多问题。

有时候程序运行到一半就自动闪退了,可能的是存储空间的问题,改了存储位置之后就好了。

测试结果及分析:

主界面设计

输入

需要输入的数据还算较多的,包括学期总数,一学期的学分上限,每门课的课程号(固定占3位的字母数字串)、学分和直接先修课的课程号。

弧尾和弧头指的是先修关系。

输入完所有的数据之后就会显示输出:

因为有两种编排策略,程序运行一半后就会让用户选择策略,一是各个学期的学习负担平均,二是课程集中在前几个学期中。

用户选择后,就会有相应的输出,之后可选择是否继续。

结束程序:

五、设计总结

这次设计相对于我来说有点困难,需要查询很多资料,询问同学,巩固学过的知识,直到设计完成对数据结构也有了新的理解,虽然在这个设计上投入了很多,但也只能完成课题的基本要求,对于选做要求,我可能还要累计更多的知识和实践来完成。

我觉得实践比理论要重要的多,在你学习到基本的知识后你不去试着编程,就像是纸上谈兵一样,没多大作用。

我会尽量做好每个设计,减少程序中常见的语法错误,逻辑错误,减少调试分析的次数,解决问题更加细心认真些。

这个程序还是有不足的,界面看上去不太美观,可以设计的更简洁一些。

要输入很多数据,而且分的步数也多输入的时候容易出错,我就是输入了好几遍才完成整个程序的运行,还是要求用户细心些

六、源程序清单

#include

#include

#include

#include

#include

usingnamespacestd;

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

typedefintStatus;

typedefintBoolean;

#defineMAX_NAME10    

#defineMAX_CLASS_NUM100

intZ=0;

intX=0;

intterm_num,credit_lim,q=1;

typedefintInfoType;

typedefcharVertexType[MAX_NAME];

#defineMAX_VERTEX_NUM100

typedefenum{DG}GraphKind;  

typedefstructArcNode{     

intadjvex;       

structArcNode*nextarc;    

InfoType*info;     

}ArcNode;      

typedefstruct{

VertexTypedata;

ArcNode*firstarc;

}VNode,AdjList[MAX_VERTEX_NUM];

typedefstruct{

AdjListvertices,vertices2;    

intvexnum,arcnum;

intkind;

}ALGraph;

intLocateVex(ALGraphG,VertexTypeu){

inti;

for(i=0;i

if(strcmp(u,G.vertices[i].data)==0)

returni;

return-1;

}

StatusCreateGraph(ALGraph&G){

inti,j,k;

VertexTypev1,v2; 

ArcNode*p;        

printf("请输入教学计划的课程数:

");

scanf("%d",&G.vexnum);

printf("请输入课程先修关系数(弧的数目):

");

scanf("%d",&G.arcnum);

printf("请输入%d个课程的代表值(如:

c01):

\n",G.vexnum);

for(i=0;i

scanf("%s",G.vertices[i].data);

G.vertices[i].firstarc=NULL;

}

printf("请输入%d个课程的学分值:

\n",(G).vexnum);

for(i=0;i

scanf("%s",G.vertices2[i].data);

}

printf("请顺序输入每条弧的弧尾和弧头(以空格作为间隔):

\n");

for(k=0;k

scanf("%s%s",v1,v2);

i=LocateVex(G,v1);

j=LocateVex(G,v2);

p=(ArcNode*)malloc(sizeof(ArcNode));  

p->adjvex=j;

p->info=NULL;

p->nextarc=G.vertices[i].firstarc;

G.vertices[i].firstarc=p;

}

returnOK;

}

voidDisplay(ALGraphG){

inti;

ArcNode*p;

switch(G.kind){

caseDG:

printf("有向图\n");

}

printf("%d个顶点:

\n",G.vexnum);

for(i=0;i

printf("%s",G.vertices[i].data);

printf("\n%d条弧:

\n",G.arcnum);

for(i=0;i

p=G.vertices[i].firstarc;

while(p){

printf("%s→%s  ",G.vertices[i].data,G.vertices[p->adjvex].data);

p=p->nextarc;

}

printf("\n");

}

}

voidFindInDegree(ALGraphG,intindegree[]){

inti;

ArcNode*p;

for(i=0;i

indegree[i]=0;

for(i=0;i

p=G.vertices[i].firstarc;

while(p){

indegree[p->adjvex]++;

p=p->nextarc;

}

}

}

typedefintSElemType;

#defineSTACK_INIT_SIZE10

#defineSTACKINCREMENT2

typedefstructSqStack{

SElemType*base;

SElemType*top;

intstacksize;

}SqStack;

StatusInitStack(SqStack*S){

(*S).base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));

if(!

(*S).base)

exit(OVERFLOW);

(*S).top=(*S).base;

(*S).stacksize=STACK_INIT_SIZE;

returnOK;

}

voidClearStack(SqStack*S){

S->top=S->base;

}

StatusStackEmpty(SqStackS){

if(S.top==S.base)

returnTRUE;

else

returnFALSE;

}

StatusPop(SqStack*S,SElemType*e){

if((*S).top==(*S).base)

returnERROR;

*e=*--(*S).top;

returnOK;

}

StatusPush(SqStack*S,SElemTypee){

if((*S).top-(*S).base>=(*S).stacksize){

(*S).base=(SElemType*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));

if(!

(*S).base)

exit(OVERFLOW);

(*S).top=(*S).base+(*S).stacksize;

(*S).stacksize+=STACKINCREMENT;

}

*((*S).top)++=e;

returnOK;

}

Statuszxf(ALGraphG){

intz=0;

for(inti=0;i

z+=atoi(G.vertices2[i].data);

}

returnz;

}

typedefintpathone[MAX_CLASS_NUM];

typedefintpathtwo[MAX_CLASS_NUM];

StatusTopologicalSort(ALGraphG){

 

inti,k,count,indegree[MAX_VERTEX_NUM];

boolhas=false;

SqStackS;

pathonea;

pathtwob;

ArcNode*p;

FindInDegree(G,indegree);

InitStack(&S);

for(i=0;i

if(!

indegree[i])

Push(&S,i);

}

count=0;

while(!

StackEmpty(S)){

Pop(&S,&i);

a[i]=*G.vertices[i].data;  //课程名;

b[i]=*G.vertices2[i].data;  //学分;

printf("课程%s→学分%s ",G.vertices[i].data,G.vertices2[i].data);

++count;

for(p=G.vertices[i].firstarc;p;p=p->nextarc){

k=p->adjvex;

if(!

(--indegree[k]))

Push(&S,k);

}

}

if(count

printf("此有向图有回路\n");

returnERROR;

}

else{

printf("为一个拓扑序列。

\n\n");

has=true;

}

printf("请问您想使学生在各学期中的学习负担尽量均匀(输入1)\n");

printf("还是想使课程尽可能地集中在前几个学期中(输入2)?

\n");

intpattern;

printf("请选择(1or2):

");

scanf("%d",&pattern);

FindInDegree(G,indegree);ClearStack(&S);

printf("=====================================================\n");

printf("教学计划如下:

\n");

intxq=1;

intxfh; 

intnow=0;

inttop=G.vexnum/term_num;

intpjxf=zxf(G)/term_num;  

while(xq<=term_num+1){

intresult[20];

intm=0;

xfh=0;

now=0;   

for(i=0;i

if(0==indegree[i])

Push(&S,i);

}

if(xq==term_num+1&&!

StackEmpty(S)){

printf("还有课程未安排!

\n");

}

while(!

StackEmpty(S)&&xq<=term_num){

intxf;

Pop(&S,&i);  

xf=atoi(G.vertices2[i].data);

xfh=xfh+xf;

now++;

if(xfh>credit_lim){

ClearStack(&S);

break;

}

if(pattern==1){

if(xq!

=term_num/2&&now>top){

ClearStack(&S);

now=0;

break;

}

}

if(pattern==2){

一(块)稻田一(面)队旗一(场)球赛一(把)铜号if(xq!

=1&&xq!

=term_num/2&&xq!

=term_num/2-1&&now>top){

母亲着急认真.得意主意同意因为阳光办法亲情爱情ClearStack(&S);

(5)小荷才露尖尖角,早有蜻蜓(立上头)。

now=0;

6、量词填空。

break;

10、用两个字组新字:

(如课本133页)}

重—轻圆—扁东—西生—死胖—瘦头—尾宽—窄美—丑进—出臭—香}

indegree[i]--;

for(p=G.vertices[i].firstarc;p;p=p->nextarc){

k=p->adjvex;

indegree[k]--;

女字旁:

奶、妈、姑、妹if(indegree[k]==0)

足足字旁(跳跑)亻单人旁(休体何)Push(&S,k);

}

result[m]=i;

m++;

}

if(xq<=term_num){

如:

爱(爱人)(亲爱)(爱情)(可爱)(热爱)(友爱)printf("第%d个学期的课程为:

",xq);

(8)、()像()。

for(intj=0;j

printf("课程%s",G.vertices[result[j]].data);

}

}

printf("\n");

xq++;

ClearStack(&S);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1