教学计划编制问题

教学计划编制问题

学生姓名:XX  指导老师:XXX

摘  要  本课程设计主要针对计算机系本科课程,根据课程之间的依赖关系,制定课程安排计划,并满足各学期课程数目大致相同。在课程设计中,系统开发平台为Windows XP,程序设计设计语言采用C++,程序运行平台为Windows XP,数据结构为邻接表。对于每个学期的课程数目采用了学分变量进行控制,以实现各学期课程数目大致相同。在程序设计中,采用了面向对象解决问题的方法。程序通过调试运行,初步实现了设计目标,并且经过适当完善后,将可以应用在教学中解决教学计划编制问题。

关键词  程序设计;数据结构;AOV网;邻接表;C++;课程计划

1 引  言

计算机系的学生必须要完成教学计划中规定的一系列课程,有些课程之间存在相互之间的依赖关系。比如说:《C++程序设计基础》应在《数据结构》之前开设,《大学物理(下)》必须要在《大学物理(上)》学完之后才可以学习。在教学计划编制的过程中,有一个层次的关系。因此,有一个有效、便捷的教学计划编制系统是十分重要的。

1.1 课程设计目的

本课程设计主要是针对计算机系本科课程,根据课程之间的依赖关系,制定课程安排计划,并满足各学期课程数目大致相同。

教学计划编制系统是基于C++的软件系统,通过建立AOV网,按学期对课程序号、课程代号、课程名称以及课程学分进行相应输出,并且保证用户实现自由选择专业选修课功能。

1.2 课程设计内容

教学计划编制系统主要是处理课程之间的依赖关系。表1.1列出了若干门计算机系本科课程,其中有些课程不要求先修课程,例如,C1是独立于其他课程的基础课,而有些课程却需要有先修课程,比如,学完程序设计语言C++和离散数学后才能学习数据结构。具体情况如表1.1所示。

表1.1 课程以及课程之间的依赖关系

课程代号

课程名称

先修课程

C1

高等数学

C2

计算机科学导论

C3

离散数学

C1

C4

程序设计语言C++

C1、C2

C5

数据结构

C3、C4

C6

计算机原理

C2、C4

C7

数据库原理

C4、C5、C6

先修课程规定了课程之间的依赖关系,这种关系可以用AOV网来表示,其中顶点表示课程,弧表示依赖关系,如图1.1所示。

图1.1 表1.1对应的AOV网

程序的主要功能是实现课程的排序,以满足同一学期所修的课程相互之间无依赖关系,并且已修完其所有先修课程。另外,设置学分变量,控制每个学期的课程量基本均匀。

2 概要设计

2.1 设计思路

数据结构课程主要讨论数据表示和数据处理的基本问题。数据要能被计算机处理,首先必须能够存储在计算机的内存中,这项任务称为数据表示,数据表示的核心任务是数据结构的设计;一个实际问题的求解必须满足各项处理要求,这项任务称为数据处理,数据处理的核心任务是算法设计。

本课程设计是基于C++程序设计语言实现的。C++语言的主要特点表现在两个方面,一是全面兼容C,二是支持面向对象的方法。因此,C++既支持面向过程的程序设计,又支持面向对象的程序设计。

C++语言最有意义的方面是支持面向对象的特征,基于对象的程序是以类和对象为基础的,程序的操作是围绕对象进行的。在此基础上利用了继承机制和多态性,就成为面向对象的程序设计。

数据结构中的数据表示和数据处理问题都可以通过C++类中数据和对数据进行操作的函数来实现。

2.2 数据表示

教学计划编制问题中,操作对象是课程。课程之间的依赖关系用AOV网表示, AOV网的构造采用邻接表实现。因此,本程序设计定义了两个类:课程类和邻接表类。

课程类(Lesson)添加了5个私有成员变量用来定义课程的5个属性:课程代号、课程名称、课程序号、课程学分以及是否被选择过的课程标记。同时还定义了8个成员函数,已实现相关的操作功能。

邻接表类(ALGraph)定义了2个整型成员变量和1个结构体数组来存放顶点数、边数和顶点表。同时还定义了4个成员函数实现用来实现AOV网的构造、删除、排序以及相关输出功能。

2.3 数据处理

数据处理必须借助函数来实现。本程序设计通过调用类的各种成员函数实现各种需要操作。

课程类(Lesson)的成员函数如表2.1所示。

表2.1 Lesson类的成员函数

函数名称

功能声明

void SetLes()

对课程各种属性进行赋值

string GetNum()

获得课程代号

string GetName()

获得课程名称

float GetLesScore()

获得课程学分

int GetLesNo()

获得课程序号

bool GetSelect()

获得是否选择过的标志变量

void SetSelect()

设置选择控制标志变量,以避免重复选课

void SetName()

单独定义设置课程名称的函数,以方便一些操作

邻接表类(ALGraph)的成员函数如表2.2所示。

表2.2 ALGraph类的成员函数

函数名称

功能声明

ALGraph()

构造函数

~ALGraph()

析构函数

void TopSort()

实现AOV网中顶点的排序并进行相应的输出

void BalanScore()

平衡每次输出的顶点的数目

3 详细设计

3.1 课程类的定义

课程类(Lesson)添加了5个私有成员变量:LesNum (课程代号)、LesName(课程名称)、LesScore(课程学分)、LesNo(课程序号)以及Select(是否被选择过的课程标记),分别用来定义课程的5个属性;同时还定义了8个成员函数:SetLes(对课程各种属性进行赋值)、GetNum(获得课程代号)、GetName(获得课程名称)、GetLesScore(获得课程学分)、GetLesNo(获得课程序号)、GetSelect(获得是否选择过的标志变量)、SetSelect(设置选择控制标志变量)和SetName(单独定义设置课程名称),用来实现相关的操作功能。

计算机系一共有65门课程,其中相互之间存在依赖关系的课程有56门,另外9门为独立课程,不存在依赖关系。Lesson B[65]定义课程类的对象数组,可以通过调用课程类的各种成员函数对65门课程的课程序号、课程代号、课程名称以及课程学分等等进行操作。

3.2 邻接表类的定义

邻接表是一种顺序存储与链接存储相结合的存储方法。在邻接表中存在两种结点结构:顶点表结点和边表结点,如图3.1所示。

              顶点表结点                        边表结点

图3.1邻接表表示的结点结构

采用C++中的结构类型描述上述结点,用 C++中的类实现基于邻接表存储结构下图的各种数据类型和操作功能。

由于采用了C++的模板机制,邻接表中的数据元素可以是任意的。在本次课程设计中,邻接表中的数据元素初始化为课程类对象。

3.3 重要函数的实现

(1)邻接表构造函数ALGraph

邻接表构造函数ALGraph(T a[],int n,int e,int edge[][73]) ,初始化一个有n个顶点、e条边和73个依赖关系的AOV网。当定义一个邻接表类的对象时,调用该构造函数,通过实参与形参相结合,实现课程信息的存储,建立AOV网,实现课程及课程之间的关系。流程图如图3.2所示。

图3.2 邻接表ALGraph的构造函数

(2)邻接表成员函数TopSort

邻接表成员函数TopSort(T OutLes[10][100],T B[65])按批次扫描AOV网,每次扫描后都将得到的入度为0的顶点依次存入数组的每行,同时对存入顶点的后继顶点进行入度减1操作。不同批次扫描得到的顶点存在数组的不同列。在此函数中通过用户的输入,还实现了专业课选择操作,并且实现了相关的输出功能。

邻接表成员函数TopSort流程图如图3.3所示。

  

(3)邻接表类成员函数BalanScore

邻接表类成员函数BalanScore(T OutLes[10][100],int count,int s,float score,T B[65])主要通过设置学分变量对每个学期的课程量进行控制,以实现不同学期的课程数目大致相等。对于某个学期课程学分未达到最少修读学分的问题,主要通过插入独立课程补足学分解决,同时在插入的同时设置学分上限,以免超过学分修读范围。最后将课程信息按不同学期依次进行输出。

邻接表类成员函数BalanScore流程图如图3.4所示。

4 运行环境与测试结果

4.1 运行环境

在本课程设计中,系统开发平台为Windows XP,程序运行环境为Visual C++ 6.0,程序设计语言为C++。Visual C++一般分为三个版本:学习版、专业版和企业版,不同版本适合于不同类型的应用开发。实验中可以使用这三个版本的任意一种,在本课程设计中,以Visual C++ 6.0为编程环境。

Visual C++以拥有语法高亮IntelliSense(自动编译功能)以及高级除错功能而著称。比如,它允许用户进行远程调试单步执行等。还有允许用户在调试期间重新编译被修改的代码,而不必重新启动正在调试的程序。其编译及建置系统以预编译头文件、最小重建功能及累加链接著称。这些特征明显缩短程式编辑、编译及链接的时间花费,在大型软件计划上尤其显著。

Visual C++ 6.0秉承Visual C++ 以前版本的优异特性,为用户提供了一套良好的开发环境,主要包括文本编辑器、资源编辑器、工程创建工具和Debugger调试器等等。用户可以在集成开发环境中创建工程,打开工程,建立、打开和编辑文本,编译、链接、运行和调试应用程序。

4.2 测试结果

(1)对所有课程输出情况的测试

在主函数运行初,先利用课程类定义了对象数组,通过对象数组调用了各种成员函数,实现对计算机系本科课程信息的总体输出。同时,使用制表符和设置宽度函数,调整输出结果,使查看更清楚。

计算机系本科课程信息部分输出如图4.1所示。

图4.1部分本科课程输出

(2)对利用学分均匀每学期课程量的测试

输出数组OutLes[10][100]第一行元素保存的课程名称,即第一学期课程名称,独立课程暂时不计入内。如图4.2所示。

图4.2排序输出及已选学分

学分未达到修读要求,根据提示选择可选的独立课程补足学分。

具体情况如图4.2、4.3和4.4所示。

图4.3提示输入选择课程的序号

图4.4提示与选择

当所选课程的学分已大于学分修读下限时,此时停止选择,输出第1个学期的课程信息。

第1个学期的课程信息输出情况如图4.4所示。

图4.4第1个学期课程信息

(3)对选择专业选修课的测试

当排序输出过程中遇到专业选修课时,可以通过根据提示输入所选课来进行选择,如图4.5所示。

图4.5选择专业选修课

(4)对计算机系本科课程安排计划的输出测试

通过对课程排序、保存、判断、选择和插入等一系列操作,最终解决计算机系本科课程的编制的问题,并输出结果。

前3个学期的课程安排计划输出如图4.6、4.7和4.8所示。

图4.6第1个学期的课程安排计划

图4.7第2个学期的课程安排计划

图4.8第3个学期的课程安排计划

5 结束语

这次课程设计内容是计算机系本科课程教学计划编制,这对我来说是个很有挑战性的任务,虽然只编制出了教学计划,但通过两个星期的设计也从中学到了不少,更深刻地理解了课本中的内容。

数据结构是计算机及相关专业的一门重要的专业基础课,也是计算机及相关专业考研和水平等级考试的必考科目,而且正逐渐发展成为众多理工专业的热门选修课。要从事与计算机和科学与技术相关的工作,尤其是计算机应用领域的开发和研制工作,必须具备坚实的数据结构基础。并且,数据结构是一门实践性较强的课程,为了学好这门课程,必须在掌握理论知识的同时,加强上机实践。同时再次深刻理解了C++中类的思想和实现,数据结构的概念和相关操作。根据实际问题的需要,对各方面的优缺点加以综合平衡,从中选择比较适宜的数据结构和实现方法。

在本次课程设计中,我明白了理论与实际结合的和总要性,培养了基本的、良好的程序设计技能,提高了综合运用所学知识的能力。通过本次课程设计,我学到了很多东西。对我个人编程动手能力有一定的提高,使我知道编程不是简单的写作业。一个系统,我们要从各方面考虑,有可能出现的问题是要事先考虑清楚的。同时,在设计初期一定要选择好数据结构,因为这将影响到整个系统的可扩展性。而且,我在编程过程中,更加认识到了C++语言的魅力和精确。一些以往中忽视掉的和误解的概念,也在这次编程中有新的理解和感悟。我也总结了不少有利的编程习惯。比如,每写一个函数就测试一下功能是否正确,合理的书写注释,遇到难题时,最好的方法是另外编写一个小的程序,测试其错误的地方以便加以修该。定义在主函数中的变量,大多数是要在多个函数中要用到的。我发现,将函数的参数命名为我的变量名,给我省下不少麻烦。这些都是在不断的调试和改错中,提取出来的经验。可能这些经验已经被大多数编程者知晓,但我的亲身体验让我更加理解这些被提倡的习惯。

在这次课程设计中曾遇到了不少问题,就单凭我一个人的能力很难准时有效的完成这次课程设计。在此,我衷心感谢我的指导老师——XXX老师。黄老师对工作认真负责,耐心辅导,知识丰富。在这次课程设计中给了我很大的帮助。他严谨的治学精神和深厚的理论水平都使我获益匪浅。同时还要感谢我的同学,他们为我提出了很多有用的建议,帮助我完成了这次的课程设计。最后也要感谢我们学校为我们提供良好的编程环境,使我们能够按时完成任务。

参考文献

[1]  G.Perry. C++程序设计教程. 北京:清华大学出版社,1994

[2]  Kenneth A.Reek . 徐波. C和指针. 北京:人民邮电出版社,2008

[3]  G.Perry. C++程序设计教程. 北京:清华大学出版社,1994

[4]  王为青,刘变红 . C语言高级编程及实例剖析 . 北京:人民邮电出版社,2007

[5]  严蔚敏 等 .数据结构(C语言版).北京:清华大学出版社,1997

[6] 周晓聪,李文军,李师贤. 面向对象程序设计——实践与提高. 中山大学计算机科学学院讲义,1999

附录:源程序清单

// 程序名称:graph.h,graph.cpp,information.h,main.cpp

// 程序功能:采用面向对象方法设计程序,解决教学计划编制问题

// 程序作者:XX

// 最后修改日期:2009-9-18

//邻接表头文件

//采用邻接表来存储图的顶点和边

#ifndef GRAPH_H                  //定义头文件

#define GRAPH_H

#include<string>               

using namespace std;

//定义边表结点

struct ArcNode                               

{

int adjvex;                 //邻接点域

ArcNode *next;

};

//定义顶点表结点

template<class T>

struct VertexNode                        

{

T vertex;                           //数据域

int indegree;                       //入度

ArcNode *firstedge;

};

const int MaxSize=56;        //图的最大顶点数

template<class T>

class ALGraph

{

public:

ALGraph(T a[],int n,int e,int edge[][73]);   //构造函数,初始化一个有n个顶点e条边73个依赖关系的图

~ALGraph();   //析构函数,释放邻接表中各边表结点的存储空间

void TopSort(T OutLes[10][100],T B[64]) ;//排序并进行相应的输出,按批次保存顶点,并且每次保存的顶点入度都为0

void BalanScore(T OutLes[10][100],int count,int s,float score,T B[64]);//平衡每次输出的顶点的量

private:

VertexNode<T> adjlist[MaxSize];       //存放顶点表的数组

int vertexNum,arcNum;                 //图的顶点数和边数

};

#endif

//定义邻接表的cpp文件

#include<iostream>

#include "graph.h"//引入头文件

//邻接表构造函数ALGraph

template<class T>

ALGraph<T>::ALGraph(T a[],int n,int e,int edge[][73])

{

    int i1,j1;   //边所依附的两个顶点的序号                         

int lat=-1;

vertexNum=n;arcNum=e;

    //输入顶点信息,初始化顶点表

for(int i=0;i<vertexNum;i++)         

{

adjlist[i].vertex=a[i];     //a[i]为输入的课程信息,通过实参与形参结合实现课程信息存储

adjlist[i].firstedge=NULL;

adjlist[i].indegree=0;

}

    

//根据数组中调出的每一条边的信息,初始化边表,并在相应的边表中插入结点

for(int k=0;k<arcNum;k++)  

{

    

    i1=edge[0][++lat];

j1=edge[1][lat];

        cout<<i1<<"->"<<j1<<endl;

ArcNode *s; s=new ArcNode;  s-> adjvex=j1;    //生成一个边表结点s

s->next=adjlist[i1].firstedge;     //将结点s插入到结点i的边表的表头

adjlist[i1].firstedge=s;   //最后生成i->j

adjlist[j1].indegree=adjlist[j1].indegree+1; //入度加1

}

}

//邻接表的析构函数~ALGraph

template<class T>

ALGraph<T>::~ALGraph()

{

for(int i=0;i<vertexNum;i++)                //依次删除顶点结点

{

ArcNode * p=adjlist[i].firstedge;

while(p!=NULL)                             //循环删除边结点

{

adjlist[i].firstedge=p->next;

delete p;

p=adjlist[i].firstedge;              

}

}

}

//排序并进行相应的输出,按批次保存顶点入二维数组OutLes,并且每次保存的顶点入度都为0

template<class T>

void ALGraph<T>::TopSort(T OutLes[10][100],T B[65])

{   

//采用顺序栈并初始化,累加器初始化

int count=-1;

int top=-1;

int s;

int S[100];

int b=0;

int m;

    //按批次将入度为0的顶点入栈

for(int i=0;i<vertexNum; i=i+m   )               

{  

count++;

for(int k=0;k<vertexNum;k++)

{

if(adjlist[k].indegree==0)  S[++top]=k;

}

m=top+1;

s=0;

while(top!=-1)                

{

int j=S[top--];

OutLes[count][s++]=adjlist[j].vertex;//用数组OutLes保存每次入栈的入度为0的顶点

adjlist[j].indegree--;//将保存过的顶点入度减1,从而为负数,避免重复入栈

ArcNode *p;p=adjlist[j].firstedge;  

//扫描顶点表,找出顶点j 的所有出边,并将其后继结点的入度减1

while(p!=NULL)

{

int k=p->adjvex;

adjlist[k].indegree--;            //将入度减1

p=p->next;

}

}

//对每个顶点的相关信息进行输出,暂时不计独立的顶点

//在本程序中顶点的类型其实就是课程类

//所以下面的循环就是对课程的课程名称进行输出,暂时不计独立的科目

for( ;b<count+1;b++)

{

            cout<<endl;

cout<<"第"<<b+1<<"个学期课程的课程名称如下:"<<endl;

cout<<"说明:独立的课程暂时不计入内"<<endl;

cout<<endl;

float score=0;

for(int a=0;a<s;a++)

{

    //对专业选修课进行选择

if(OutLes[b][a].GetName()=="JAVA程序设计(C#程序设计)")

{ cout<<"请从JAVA程序设计和C#程序设计中任选一门您的专业选修课"<<endl;

string p[2]={"JAVA程序设计","C#程序设计"};

int q;

cout<<"选择JAVA程序设计,则请输入0;否则输入1"<<endl;//按照输出提示对专业选修课进行选择

//如果用户输入不合法,则必须重新输入

do{

cin>>q;

}while(!(q==0||q==1));

cout<<p[q]<<endl;

OutLes[b][a].SetName(p[q]);

}

else

cout<<OutLes[b][a].GetName()<<endl;//提示用户所选的课程名称

score=score+OutLes[b][a].GetLesScore();//对学分进行统计

}

BalanScore(OutLes, count, s,score, B);

}

}

}

//平衡每次输出的顶点的量

//在本例中其实就是利用学分变量对每个学期的课程量进行控制

template<class T>

void ALGraph<T>::BalanScore(T OutLes[10][100],int count,int s,float score,T B[65])

{

//学分的控制范围为21<score<29

if(!(21<score))

{

float Allscore=163;//总学分数为163

float Avescore=Allscore/7;//每个学期平均学分数

cout<<"\n每个学期平均学分数为:"<<Avescore<<"\n您每个学期所选的课程学分应大于"

<<Avescore-2<<"且小于"<<Avescore+6<<endl;//输出每个学期的平均学分数以及学分修读范围要求

        

//对课程量不够的学期,增加一定量的课程,直到达到学分修读要求为止

cout<<"\n本学期课程量不够,请从以下课程中选择一定量的课程,以满足学分修读要求\n"<<endl;

for(int i=56;i<65;i++)

{

//对已选的课程进行排除,避免重复选择

if(!B[i].GetSelect())

cout<<"序号:"<<B[i].GetLesNo()<<"  "<<"课程代号:"

<<"  "<<B[i].GetNum()<<"\t"<<"课程名称:"<<" "<<

setw(32)<<B[i].GetName()<<"\t"<<"课程学分:"<<"  "<<B[i].GetLesScore()

<<"\t"<<endl;

}

//用学分对每个学期的课程量进行控制

while(!((Avescore-2)<score&&score<(Avescore+6)))

{

cout<<"\n您现在已选学分为:"<<score<<endl;//提示用户已选学分数

cout<<"请您输入所选课程的序号"<<endl;

int Number;

cin>>Number;       //用户输入所选课程序号

if((score+B[Number].GetLesScore())<29)

{

cout<<"您所选的课程为:"<<B[Number].GetName()<<endl;//提示用户所选的课程名称

OutLes[count][s++]=B[Number];

score+=B[Number].GetLesScore();//学分累加

B[Number].SetSelect(true);//对已选课程进行标记

}

//对学分超过的情况进行重新选课

else cout<<"您所选课程的学分超过了学分修读范围,请重新选课"<<endl;

}

}

//对每个学期的课程进行输出,完成教学计划的编制

cout<<"\n第"<<count+1<<"个学期的课程如下:\n"<<endl;

for( int h=0;h<s;h++)

{

//使用制表符和设置宽度函数对输出信息进行美化,方便用户查看

    

       

            cout<<"序号:"<<OutLes[count][h].GetLesNo()<<"  "<<"课程代号:"

<<"  "<<OutLes[count][h].GetNum()<<"\t"<<"课程名称:"<<" "<<

setw(22)<<OutLes[count][h].GetName()<<"\t"<<"课程学分:"

<<"  "<<OutLes[count][h].GetLesScore()

<<"\t"<<endl;

}

}

//计算机系本科课程信息

//定义头文件

#ifndef INFORMATION_H           

#define INFORMATION_H  

#include<string>               

using namespace std;

//参与依赖关系的课程的代号

string newLesNum[56]={"C1","C2","C3","C4","C5","C6","C7", "C8","C9","C10",

"C11","C12","C13","C14","C15","C16","C17","C18","C19","C20","C21","C22",

"C23","C24","C25","C26","C27","C28","C29","C30","C31","C32","C33","C34",

"C35","C36","C37","C38","C39","C40","C41","C42","C43","C44","C45","C46",

"C47","C48","C49","C50","C51","C52","C53","C54","C55","C56"};

//独立的课程的代号

string depLesNum[9]={"L1","L2","L3","L4","L5","L6","L7","L8","L9"};

//参与依赖关系的课程的名称

string newLesName[56]={

    "C++程序设计基础",

"高等数学A(一)",

"计算机科学导论",

"大学英语(一)",

"VC++可视化课程设计",

"大学物理(上)",

"高等数学A(二)",

"线性代数",

"体育(一)",

"大学英语(二)",

"体育(二)",

"VC++课程设计",

"大学物理(下)",

"大学物理实验",

"汇编语言A",

"计算机电路",

"离散数学",

"体育(三)",

"大学英语(三)",

"数据结构A",

"数据库基本原理与技术",

"大学英语(四)",

"体育(四)",

"概率论与数理统计B",

"数字逻辑与数字系统",

"数据库系统应用课程设计",

"编译原理与技术A",

"操作系统B",

"计算机网络原理与技术B",

"计算机组成原理",

"数据结构课程设计",

"专业英语",

"计算机组成原理课程设计",

"JAVA程序设计(C#程序设计)",

"XML与Web应用技术",

"高级操作系统分析",

"接口技术",

"嵌入式系统B",

"软件工程A",

"网络系统课程设计",

"电子商务软件及其开发技术",

"多媒体技术",

"算法分析与设计",

"计算机体系结构",

"方向课程综合课程设计",

"软件工程课程设计",

"微机生产实习",

"图形图象处理技术",

"计算机网络工程设计",

"大型数据库设计",

"分布式数据库管理",

"嵌入式操作系统",

"嵌入式系统设计",

"网络管理及安全",

"中间件技术",

"人工智能导论"

};

//独立的课程的名称

string depLesName[9]={

    "大学生学习方法指导",

"军事理论",

"军训",

"大学生心理健康",

"思想道德修养及法律基础",

"中国现代史纲要",

"人文类选修课",

"马克思主义基本原理",

"毛泽东思想、邓小平理论和“三个代表”重要思想概论"

};

//参与依赖关系的课程的学分

float newLesScore[56]={

    3,5,2,4,3,2.5,5,2,1.5,4,1.5,2,3.5,2,3,5,2.5,1.5,4,

3,3,4,1.5,2.5,3.5,2,3,2,3,3,2,2,2,3,3,2,3,2,3,2,2,

2,2.5,2,2,2,2,2.5,3,2,2,2,2,3,2,2

};  

//独立的课程的学分

        

float depLesScore[9]={0.5,1,3,1,2,2,8,3,3};

//为所有课程编的序号,以方便对课程进行各种操作

int newLesNo[65];

//课程之间的依赖关系

int fomer=2;

int later=73;

int edge[2][73]=

{{0,1,1,1,3,8,0,4,5,5,0,2,4,5,1,6,7,10,9,0,

2,16,0,16,18,17,0,6,16,15,20,19,19,19,24,

19,21,24,19,29,27,29,29,27,19,33,28,19,20,33,

19,20,33,19,33,27,37,38,43,41,28,39,38,38,35,

37,37,28,39,20,38,29,43},   

{4,5,6,7,9,10,11,11,12,13,14,14,14,15,16,16,

16,17,18,19,19,19,20,20,21,22,23,23,23,24,25,

26,27,28,29,30,31,32,33,34,35,36,37,37,38,38,

39,40,40,40,41,41,41,42,42,43,44,45,46,47,48,

48,49,50,51,51,52,53,53,54,54,55,55}};

#endif;

//引入头文件

#include<iostream>

#include<iomanip>

#include<string>

#include"graph.cpp"

#include"information.h"

using namespace std;//使用命名空间

//课程类的定义

class Lesson

{

public:

//对课程的各种属性进行赋值

    void SetLes(string inLesNum,string inLesName,float inLesScore,int inLesNo,bool inSelect=false);

string GetNum(){return LesNum;}             //获得课程代号

string GetName(){return LesName;}             //获得课程名称

float GetLesScore(){return LesScore;}   //获得课程学分

int GetLesNo(){return LesNo;}//获得课程序号

bool GetSelect(){return Select;}//获得是否选择过的标志变量

void SetSelect(bool Select){this->Select=Select;}//设置选择控制标志变量,以避免重复选课

void SetName(string newname){LesName=newname;}//单独定义设置课程名称的函数,以方便一些操作

private:

string LesNum;//课程代号

string LesName;//课程名称

float LesScore;//课程学分

int LesNo;//课程序号

bool Select;//是否选择过的标志

};

//成员函数的实现

void Lesson::SetLes(string inLesNum,string inLesName,float inLesScore,

int inLesNo,bool inSelect)

{

LesNum=inLesNum;

LesName=inLesName;

LesScore=inLesScore;

LesNo=inLesNo;

Select=inSelect;

}

//主函数

int main()

{

//给对每门课程编个序号

for(int k=0;k<65;k++)

{

newLesNo[k]=k;

}

int n=65;  //65门课程

int e=73; //所有课程中一共有73个依赖关系

Lesson B[65];

//输出存在依赖关系的课程信息

int x,y,z,u,v,w,j;

x=y=z=u=v=w=j=0;

cout<<"参与依赖关系的课程如下:"<<endl;

    cout<<endl;

for(int i=0;i<56;i++)

{

//利用数组对课程类对象成员进行赋值

B[i].SetLes(newLesNum[x++],newLesName[y++],newLesScore[z++],newLesNo[j++]);

//使用制表符和设置宽度函数对输出信息进行美化,方便用户查看

cout<<"序号:"<<B[i].GetLesNo()<<"  "<<"

课程代号:"<<"  "<<B[i].GetNum()<<"\t"<<"课程名称:"<<" "<<

setw(22)<<B[i].GetName()<<"\t"<<"课程学分:"<<"  "<<B[i].GetLesScore()

<<"\t"<<endl;

}

cout<<endl;

//输出不存在依赖关系的课程信息

cout<<"不参与依赖关系的课程即独立课程如下:"<<endl;

cout<<endl;

for(;i<65;i++)

{

B[i].SetLes(depLesNum[u++],depLesName[v++],depLesScore[w++],newLesNo[j++]);

cout<<"序号:"<<B[i].GetLesNo()<<"\t"<<"  "<<

"课程代号:"<<"  "<<B[i].GetNum()<<"\t"<<"课程名称:"<<" "<<

setw(22)<<B[i].GetName()<<"\t"<<"课程学分:"<<"  "<<B[i].GetLesScore()

<<"\t"<<endl;

}

    cout<<endl;

//输出依赖关系

    cout<<"课程之间的依赖关系如下:"<<endl;

cout<<"说明:前一个数字为先修课程的序号,后一个数字为后继课程的序号"<<endl;

    cout<<endl;

    ALGraph<Lesson> Maps(B,56,73,edge);//图的初始化

Lesson M[10][100];

Maps.TopSort(M ,B);//调用函数对课程关系进行处理并进行相应的输出

//提示用户课程教学计划编制完毕

cout<<"\n计算机系本科课程教学计划编制完毕!"<<endl;

return 0; //正确运行完毕

}