📄 arrage_main.cpp
字号:
#include "stdafx.h"
#include "arrange_main.h"
//全局变量
float LimitedScore; //每学期的学分上限
int Subjects; //课程总数
int Terms; //学期总数
int *Flag; //标志数组,其元素内容,表示对应位置的课程(顶点)是否可修
//0表示该课程的对应的某一先修课程还没被修或正在修,所以该课程暂时不可修
//-1表示该课程的对应的某一先修课程正在被修,所以该课程暂时不可修
//1表示该课程的对应的某一先修课程已被修完,所以该课程可能可以被修
//只有当该课程的所有的先修课程对应的flag为1,该门课程才可被修
VertexType *V; //VertexType数组
Graph G; //有向图G
void main(){
if(!Initial())
return;
if(!Input()){
Destroy();
return;
}
if(!Output()){
Destroy();
return;
}
Destroy();
}
Status Initial(){
//初始化程序,进行基本信息输入,且进行基本的检查,看课程总数、学期总数有无超出本程序的最大范围
//若无错则返回OK,否则返回ERROR
int i;
printf("****************************************************************************\n");
printf("******************************教学计划安排程序******************************\n");
printf("****************************************************************************\n\n");
printf("请输入“学期总数”、“课程总数”、“每学期的学分上限”(数据间用空格键隔开)\n");
scanf("%d%d%f",&Terms,&Subjects,&LimitedScore);
if(Subjects>MAXSUBJECTS || Terms>MAXTERMS){
printf("输入的“学期总数”或“课程总数”超出本程序范围,不能安排教学计划\n程序中止!!!\n"); ///////错误处理1
return ERROR;
}
Flag=(int *)malloc(Subjects*sizeof(int));
if(!Flag) exit(OVERFLOW);
for(i=0;i<Subjects;i++) //初始化Flag数组元素为0
Flag[i]=0;
V=(VertexType *)malloc(Subjects*sizeof(VertexType));
if(!Terms) exit(OVERFLOW);
return OK;
}
Status Input(){
//通过输入建立一用“邻接表”存储的有向图保存课程信息
int i;
printf("请输入课程信息:“课程代号”、“课程学分”、“先修课程代号”\n");
printf("课程代号为3位数字字母字符\n");
printf("数据用空格建隔开,输入完一门课程信息后按回车键后,输入下一门课程\n");
printf("课程无先修课程则先修课程代号输入字符‘#’\n多个修课程代号用分号隔开(先修课程不多于5门)\n");
if(!CreateGraph(G,Subjects)){
printf("输入的先修课程代号不在所要学的课程的范围,不能安排教学计划\n程序中止!!!\n"); ///////错误处理2
return ERROR;
}
for(i=0;i<Subjects;i++)
if(G.vertices[i].data.score>LimitedScore){
printf("某单科的学分已超出每学期的学分上限,不能安排教学计划\n程序中止!!!\n"); ///////错误处理3
return ERROR;
}
return OK;
}
Status Output(){
//对生成的有向图进行拓扑排序后,根据每学期的学分上限,按照课程尽可能地集中在前几个学期中的原则,进行教学计划安排
//结果输出到文件“TeachingArrange.txt”中
int i,w;
float termSum,totalTermS=0;
FILE *fp;
fp=fopen("TeachingArrange.txt","w+");
if(fp==NULL) {printf("cannot open file\n");exit(0);} //若打开文件失败,则退出程序
for(i=0;i<Subjects;i++)
totalTermS+=G.vertices[i].data.score;
if(totalTermS>Subjects*LimitedScore){
printf("课程太多,不能安排教学计划\n程序中止!!!\n"); ///////错误处理4
fprintf(fp,"课程太多,不能安排教学计划\n程序中止!!!\n");
fclose(fp);
return ERROR;
}
if(!TopologicalSortGraph(G,V)){
printf("课程间的先修关系矛盾,不能安排教学计划\n程序中止!!!\n"); ///////错误处理5
fprintf(fp,"课程间的先修关系矛盾,不能安排教学计划\n程序中止!!!\n");
fclose(fp);
return ERROR;
}
fprintf(fp,"**************************************************************************************\n");
fprintf(fp,"***********************************教学计划安排***************************************\n");
fprintf(fp,"**************************************************************************************\n\n");
fprintf(fp," 学期总数:%d 课程总数:%d 学分总数:%.1f\n\n",Terms,Subjects,totalTermS);
fprintf(fp," 课程代号 课程学分 先修课程\n");
for(i=0;i<Terms;i++){
fprintf(fp,"\n第%d学期",i+1);
termSum=0;
for(w=0;w<Subjects;w++) //找第一个为Flag为0的下标
if(Flag[w]==0)
break;
if(w<Subjects){
for(;w<Subjects;w++) //安排本学期所要修的课程
if(Flag[w]!=1) //不为已修的课程
if(termSum+V[w].score<=LimitedScore && CheckFlag(V,w)){
Flag[w]=-1;
termSum+=V[w].score;
}
fprintf(fp,"(共修学分%.1f)\n",termSum);
for(w=0;w<Subjects;w++) //输出本学期所要修的课程
if(Flag[w]==-1){
fprintf(fp,"%25s%15.1f %-20s\n",V[w].code,V[w].score,V[w].preCode);
Flag[w]=1;
}
}
else //本学期无课程
fprintf(fp,"(本学期无课程)\n");
}
for(w=0;w<Subjects;w++)
if(Flag[w]==0){
printf("根据学期总数、每学期的学分上限、课程总数及其的学分,不能安排教学计划\n程序中止!!!\n"); ///////错误处理6
fprintf(fp,"根据学期总数、每学期的学分上限、课程总数及其的学分,不能安排教学计划\n程序中止!!!\n");
fclose(fp);
return ERROR;
}
printf("教学计划结果查看“TeachingArrange.txt”文件\n程序正常结束!!!\n");
fclose(fp);
return OK;
}
Status Destroy(){
//销毁,清理工作
free(Flag);
free(V);
DestroyGraph(G);
return OK;
}
Status CheckFlag(VertexType *v,int n){
//检查该课程是否可修,即判断其先修课程有否修完
//可修返回TRUE,否则返回FALSE
int j,k,l,test=1;
char *str;
l=strlen(v[n].preCode);
if(l==1)
return TRUE;
str=v[n].preCode;
for(k=0;k<l;k+=4){
for(j=0;j<Subjects;j++) //若有先修课程,必找到与先修课程对应的j
if(!strncmp(str,v[j].code,3)){
test*=Flag[j];
if(test<=0)
return FALSE;
break;
}
str+=4;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -