教学计划编制问题
学生姓名: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; //正确运行完毕
}