栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

教学计划编制问题--(图的应用)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

教学计划编制问题--(图的应用)

该项目为数据结构课程设计

-–源码–https://github.com/JlaYun/C-

题目:
大学的每个专业都要制定教学计划。假设任何专业都有固定的学习年限,每学年含两学期,每学期的时间长度和学分上限值均相等。每个专业开设的课程都是确定的,而且课程在开设时间的安
排必须满足先修关系。每门课程有哪些先修课程是确定的,可以有任意多门,也可以没有。每门课
恰好占一个学期。试在这样的前提下设计一个教学计划编制程序。
要求:
(1) 输入参数应包括:学期总数,一学期的学分上限,每门课的课程号(可以是固定占3位的
字母数字串)、学分和直接先修课的课程号;
(2) 应允许用户指定下列两种编排策略之一:一是使学生在各学期中的学习负担尽量均匀;二
是使课程尽可能地集中在前几个学期中;
(3) 若根据给定的条件问题无解,则报告适当的信息;否则将教学计划输出到用户指定的文件
中。计划的表格格式可以自己设计;
(4) 可设学期总数不超过12,课程总数不超过100。如果输入的先修课程号不在该专业开设的课程序列中,则作为错误处理。
逻辑我相信各位在某度已经看到很对了,这里就不对讲了,直接上代码。
从文件获取

bool Graph::ReadClassInformation( Graph *p) {
   // int choose=0;
    //ifstream file2("c://pdos.def");       //以输入方式打开文件
    //ofstream file3("c://x.123");          //以输出方式打开文件
    // file1.close();就把file1相连的文件关闭

    std::ifstream in("E:\S-ata-strcture\Ex\cmake-build-debug\new 2.txt");
    if (!in.is_open()) {     //!is_open() 判断文件是否存在
        cout << "文件不存在!" <> p->course_number;   //逐字输出

    cout<<"导入信息如下"<course_number;i++)
    {

        in >> p->course[i].id;
        in>> p->course[i].name ;
        in>>p->course[i].credit;
        cout<<"第"<course[i].id<course[i].name<course[i].credit<course[i].course_exist = true;
    }
    //输出课程信息
    int i, j;
    for (int k = 0;k < p->course_number;k++)   //将文件的信息存入    Adjmatrix 中
    {
        in >> i >> j;
        p->Adjmatrix[i][j] = 1;                   //表示课程ci是课程cj的先修课程

        }
//    for (int i = 1;i <= p->course_number;i++)
//    {
//        for (int j = 1;j <= p->course_number;j++)
//            cout <Adjmatrix[i][j] << " ";  //邻接矩阵
//        cout << endl;
//    }
    in.close();
    cout << "文件里面的课程信息已成功录入!" << endl;
    }


从键盘获取

//键盘形式输入课程信息创建图
//输入参数  1、学期总数 2、一学期的学分上限 3、课程编号 4、学分 5、直接先修课程编号
void Graph::KeyOutput(Graph* p){
     //ALGraph *G;
   // p->ALGRAPHS.ExtraInfo = (Message*)malloc(sizeof(Message));		//初始化指针
    system("cls");        //清空屏幕
    // cout << " 学期总数(有几个学期)  每学期学分上限  一学期课程总数(每学期*课程)" << endl<course->SemesterNum,&p->course->MaxCredit,&p->course->ClassSum);
        cout<<" 学期总数(有几个学期)"<>p->course->SemesterNum;
         cout<<" 每学期学分上限"<>p->course->MaxCredit;
         cout<<" 一学期课程总数(总数为:每学期*课程)"<>p->course->ClassSum;
    if (p->course->ClassSum > MaxClass) {                          // //MaxClass为学期总数
        printf("超出最大课程总数%d,请更改数据n", MaxClass);
        exit(1);
    }
    if (p->course->SemesterNum > MaxSemester) {  //SemesterNum 学期数
        printf("超出最大学期数%d,请更改数据n", MaxSemester);
        exit(1);   //退出 如return -- exit
    }
  //  cout << "请输入课程总数" << endl;
  //  cin >> p->course_number;  //从键盘输入
//    system("cls");        //清空屏幕
//    system("pause");
    cout << "您输入课程总数是"<<(p->course->SemesterNum * p->course->ClassSum) << endl;
//    printf("若您不先修可直接输入 <0>"); cout<"); cout<> p->course_number;  //获取先修的课程数目
    p->course->Apcourse=p->course_number;  //存入结构体中
    if(p->course_number==0) {
        printf("您没有输入课程信息");
       // printf("将重新从文件导入课程信息");
       // ReadClassInformation( p); //重新导入信息
        return;
    }
    int tag=0;
    cout << "请依次输入课程编号、课程名称和学分" << endl;
    system("pause");    //请按任意键继续. . .
    for (int i = 1;i <= p->course_number;i++)
        {
            cout << "第" << i << "门的";
            cout << "课程编号是:";
            cin >> p->course[i].id;
            cout << "课程名称是:";
            cin >> p->course[i].name;
            cout << "课程分数是:";
            cin >> p->course[i].credit;  // 课程编号、课程名称和学分
          //  grade += p->course[i].credit;

            p->course[i].course_exist = true;
            }
    printf("输入先修课的值是:%d",p->course_number);
    cout<Adjmatrix, 0, sizeof(p->Adjmatrix));    //初始化adjmatrix全部元素为0
    cout << "请输入课程之间的前后关系:请输入数字(由课程编号确定 每次输入一个数)" << endl;
    printf("例如 1  2 课程1是2的必修课");cout<course_number/2;k++)
    {
        cin >> i >> j;
        p->Adjmatrix[i][j] = 1;   //表示课程ci是课程cj的先修课程
    }
    cout << "键盘输入的课程信息已成功录入!" << endl;
}

修改

//修改课程信息
void Graph::Modify_course(Graph* p)
{
    //修改之前需先判断该课程编号是否在文件中
    int number=0,choice;
    string input ,Str;
    int temp=0;
    bool Ex= true;
    int tag=0;
    do{
        cout << "请输入您想修改的课程编号:" << endl;
        cin >> input;
        cout<
            for (int i = 1; i <= p->course_number; i++){
                Str = p->course[i].id;
                temp++;
                    //int strcmp(const char *input, const char *Str); //strcmp 判断是否相等 相等 为 0
            if(input==p->course[i].id){
                  printf("您要修改的课程存在");
                number= temp;
                  tag=1;
                                }
                }
              if(tag==0)
              { printf("该课程不存在");
                  return;
              }
        }
        cout<> choice;
        if (choice == 1)
        {
            cout << "请输入新的课程名称" << endl;
            cin >> p->course[number].name;
        }
        if (choice == 2)
        {
            cout << "请输入新的课程学分" << endl;
            cin >> p->course[number].credit;
        }
        cout << "修改成功" << endl;
        Ex= false;


打印在屏幕

在这里插入代码片
//输出课程信息
void Graph::Display_information(Graph* p) {
    int Choice = 0;
    printf("请输入您要输出的信息: 1(课程信息)  2、(课程的先后顺序)");
    cout << endl;
    cin >> Choice;
    if (p->course->Apcourse== 0&& p->course_number==0 ) {
        printf("没有获取到课程信息");
        cout << endl;
        return;
    }
    if (Choice == 1) {

        cout << "课程信息如下:" << endl;
        cout << "课程编号 " << "课程名称 " << "         课程学分   " << endl;
        for (int i = 1; i <= p->course_number; i++) {
            cout << std::setw(5) << p->course[i].id << "  5";
            cout << p->course[i].name << " ";
            cout << p->course[i].credit << std::setw(5) << " ";
            cout << endl;
        }
    }
    if (Choice == 2) {
        cout << endl << "课程关系矩阵:(最多为对应1-" << p->course_number<< "号课程,课程从 1 开始)" << endl;
        for (int i = 0; i <= p->course_number; i++) {
            if (i >= 10)
                cout << i << std::setw(6);
            else cout << i << std::setw(4);
        }
        cout << endl;//输出1-14
        for (int i = 0; i <= 14; i++) {
            cout << "----" << std::setw(4);//-------------
        }
        cout << endl;
        for (int i = 1; i <= p->course_number; i++) {
            for (int j = 1; j <= p->course_number; j++)
                cout << std::setw(4) << p->Adjmatrix[i][j] << " ";  //邻接矩阵
            cout << endl;
        }
    }
    if(Choice!=1&&Choice!=2)
    {
        printf("您输入的内容有误");
        cout< 

建立邻居矩阵-
用了三种方法可选–
方法1-
- -需要建立图的结构图变量

利用结构体建立邻接矩阵
//void Graph::CreatTable(ALGraph* G ,Graph* p ){
//
//    G->VexNum=p->course->ClassSum;  //获取修改的最大课程数
//    FILE* fp = fopen("E:\S-ata-strcture\Ex\cmake-build-debug\new 2.txt", "r");
//    if (NULL == fp) {
//        printf("文件路径有误!!!");
//        exit(1);
//    }
//    G->Vertics = (VexNode*)malloc(sizeof(VexNode) * G->VexNum);
//    for (int i = 0; i < G->VexNum; i++)
//        G->Vertics[i].FirstEdge = NULL;		//初始化
//    for (int i = 0; i < G->VexNum; i++) {		//读取课程信息
//        fscanf(fp, "%s%d", G->Vertics[i].Date, &G->Vertics[i].Credit);		//读取课程名称和学分
//        while ('n' != fgetc(fp)) {		//根据先修课程建立邻接表结点
//            char str[4];
//            int s;
//            fscanf(fp, "%s", str);
//            s = Locate(str);
//            if (s < 0 || s > G->VexNum) {		//判断课程是否有错误
//                printf("%s输入错误!n", G->Vertics[i].Date);
//                exit(1);
//            }
//            EdgeNode* p = (EdgeNode*)malloc(sizeof(EdgeNode));		//更新邻接表结点
//            p->AdjVex = i;
//            p->Next = G->Vertics[s].FirstEdge;
//            G->Vertics[s].FirstEdge = p;
//            G->ArcNum++;
//        }
//    }
//    fclose(fp);
//    for (int i = 0; i < G->VexNum; i++)		//更新入度
//        G->Vertics[i].InDegree=0;
//    for (int i = 0; i < G->VexNum; i++) {
//        for (EdgeNode* p = G->Vertics[i].FirstEdge; NULL != p; p = p->Next) {
//            G->Vertics[p->AdjVex].InDegree++;
//        }
//
//    }
//}

方法2- 用栈的方式。先进后出

void InitStack(SqStack &s){
    s.top=-1;
    printf("初始化完成SqStack ");    cout<
//    InitStack(s);
//    s.top=-1;
    if(s.top==MaxClass-1)return false;
    printf("进栈头是:%d",s.top);    cout<
    if(s.top==-1)return false;
//    printf("出栈头是:%d",s.top);   cout<
    if(s.top==-1)return false;
    printf("读取值时栈头是:%d",s.top);     cout<
//
//   SqStack *S;
//    S= (SqStack*)malloc(sizeof(SqStack));  //分配空间
//    InitStack(*S);
//    cout<top<course_number + 1];               //存放各结点的入度(从indegree[1]开始存放)
//    memset(indegree, 0, sizeof(indegree));          //将indegree全部赋值为0
// //   for(int i=0;icourse_number;i++)cout<course_number;i++)     //统计各结点的入度
//        for (int j = 1;j <= p->course_number;j++)
//            if (p->Adjmatrix[i][j]) indegree[j]++;
//   // for(int i=0;icourse_number;i++)cout<course_number; i++)   //入度为0,则压入栈
//    {
//        if (!indegree[i]) {     // 1、8、9
//            // printf("在拓扑中进栈"); //把i值进栈
//            StakEmpty(*S, i);        //入栈
//         //   cout << "StakEmpty 一次入栈  --" << i << endl;
//
//        }
//    }
//    cout<<"二次获取头指针"<top<top;
//    int num=0, t;
//    while(S->top!=0){  // 非空
//        printf("进入判断");
//        int TopEle;
//      //  for(int i=S->length;i>=0;i--)  //length=2
//        Pop(*S,&t); //获取栈顶元素 出栈
//        TopEle=t; cout<course_number;j++){
//            if(p->Adjmatrix[TopEle++][0]){
//                if(!--indegree[0])
//                    StakEmpty(*S,j);
//                cout << "StakEmpty 二次入栈  --" << j << endl;  //12 13
//
//            }
//        }
//    }
//
//    }

3、用栈的函数,不要定义直接用

//构造拓扑序列

void Graph::ToplSort(Graph* p, int TopSort[])
{
    int indegree[p->course_number + 1];           //存放各结点的入度(从indegree[1]开始存放)
    memset(indegree, 0, sizeof(indegree));
    for (int i = 1;i <= p->course_number;i++)     //统计各结点的入度
        for (int j = 1;j <= p->course_number;j++)
            if (p->Adjmatrix[i][j]) indegree[j]++;

    stack  s;  //创建栈
    for (int i = 1;i <= p->course_number;i++)     //入度为0,则压入栈
        if (!indegree[i]) s.push(i);                //push() 在栈顶增加元素

    int num = 0;                                  //开始进行拓扑排序
    while (!s.empty())            //栈非空 作为判断容器是否为空的函数;
    {
        int top;
        top = s.top();                            //取栈顶元素
        s.pop();                                  //出栈
        TopSort[num++] = top;       //保存栈顶元素
        for (int j = 1;j <= p->course_number;j++)
        {
            if (p->Adjmatrix[top][j])
            {
                if (!--indegree[j]) s.push(j);    //每出一个元素,则它指向的结点入度减1
            }                                     //并判断是否为0,若为零则入栈
        }
    }
}

后面为两种编排方式

//按各学期中的学习负担尽量均匀地制定教学计划
void Graph::Equality(Graph* p, int TopSort[])
{
    //存入文件中
    ofstream out("Equality-class.txt");
    int average_credit = 0;
    int semester=0;  //学期数
    for (int i = 1;i <= p->course_number;i++)     //计算课程总学分
    {
        average_credit += p->course[i].credit;
    }
    printf("总分是:%d",average_credit); cout<course->SemesterNum;                //获取聪从键盘获取的学期数目
    if(semester==NULL){
        printf("您没有输入学期数目,将按默认值8分配");    //4年制
        cout< 0)                    //总学分还剩余
    {
        int term_credit = 0;
        int term_remaine_credit = average_credit; //当前学期还能修的学分  -- 获取每学期的平均学分
        out << "第" << term_number << "学期:" << endl;
        if (remaine_credit > term_remaine_credit) //剩余总学分多于当前学期还能修的学分
        {
            while (term_remaine_credit > 0)       //当前学期还能修的学分还剩余
            {
                out << p->course[TopSort[j]].id << " ";     //j 为0 则为入栈为0的节点
                out << p->course[TopSort[j]].name << " ";
                out << p->course[TopSort[j]].credit << " ";

                term_remaine_credit -= p->course[TopSort[j]].credit;
                remaine_credit -= p->course[TopSort[j]].credit;
                term_credit += p->course[TopSort[j]].credit;
                j++;
                out << endl;
            }
            term_number++; //当前学期没有还能修的学分,换下学期
        }
        else  //剩余总学分少于或等于当前学期还能修的学分
        {
            out << p->course[TopSort[j]].id << " ";
            out << p->course[TopSort[j]].name << " ";
            out << p->course[TopSort[j]].credit << " ";

            term_remaine_credit -= p->course[TopSort[j]].credit;  //当前学期学分减去当前学科的学分
            remaine_credit -= p->course[TopSort[j]].credit;   //总学分减去当前学科的学分
            term_credit += p->course[TopSort[j]].credit;  //当前学期的分数
            j++;
            out << endl;
        }
        out << "本学期总学分为:" << term_credit << endl << endl;
    }
    out << "学期总数为:" << term_number << endl;
    out.close();
    cout << "教学计划已保存到文件Equality-class.txt 中" << endl;
}

// 可能短的时间完成学习制定教学计划
void Graph::ShortTime(Graph* p, int TopSort[]) {
    ofstream out("FinishTheProjectShort.txt");
    int term_credit;                              //学期总学分
    int term_number = 1;                          //学期编号
    int number = 0;                               //拓扑排序结果下标
    int remain_credit = 0;                        //剩余总学分
    int EachCredit = 0;
    for (int i = 1; i <= p->course_number; i++)     //计算课程总学分
    {
        remain_credit += p->course[i].credit;
    }

    EachCredit = p->course->MaxCredit;  //获取键盘设置的每学期学分上限
    // cout<<"没有输入学期数EachCredit的值是:"<
        printf("没有设置每学期的学分,默认设置为12");
        while (remain_credit > 12)   //每学期学分上限为12
        {
            term_credit = 0;
            out << "第" << term_number << "学期:" << endl;
            while (term_credit + p->course[TopSort[number]].credit < 12) {    //当前本学期总学分+下一个要安排课程的学分<学分上限12
                out << p->course[TopSort[number]].id << " ";
                out << p->course[TopSort[number]].name << " ";
                out << p->course[TopSort[number]].credit << " " << endl;
                term_credit += p->course[TopSort[number]].credit;
                remain_credit -= p->course[TopSort[number]].credit;
                number++;
            }
            term_number++;
            out << "本学期总学分为:" << term_credit << endl << endl;

            term_credit = 0;
            out << "第" << term_number << "学期:" << endl;//总学分剩余小于12时
            while (remain_credit > 0) {
                out << p->course[TopSort[number]].id << " ";
                out << p->course[TopSort[number]].name << " ";
                out << p->course[TopSort[number]].credit << " " << endl;
                term_credit += p->course[TopSort[number]].credit;
                remain_credit -= p->course[TopSort[number]].credit;
                number++;
            }
            out << "本学期总学分为:" << term_credit << endl << endl;
            out << "学期总数为:" << term_number << endl;
            out.close();
            cout<
        while (remain_credit > EachCredit)   //每学期学分上限为12
        {
            term_credit = 0;
            out << "第" << term_number << "学期:" << endl;
            while (term_credit + p->course[TopSort[number]].credit < 12)
            {    //当前本学期总学分+下一个要安排课程的学分<学分上限12
                out << p->course[TopSort[number]].id << " ";
                out << p->course[TopSort[number]].name << " ";
                out << p->course[TopSort[number]].credit << " " << endl;
                term_credit += p->course[TopSort[number]].credit;
                remain_credit -= p->course[TopSort[number]].credit;
                number++;
            }
            term_number++;
            out << "本学期总学分为:" << term_credit << endl << endl;
        }
        term_credit = 0;
        out << "第" << term_number << "学期:" << endl;//总学分剩余小于12时
        while (remain_credit > 0)
        {
            out << p->course[TopSort[number]].id << " ";
            out << p->course[TopSort[number]].name << " ";
            out << p->course[TopSort[number]].credit << " " << endl;
            term_credit += p->course[TopSort[number]].credit;
            remain_credit -= p->course[TopSort[number]].credit;
            number++;
        }
        out << "本学期总学分为:" << term_credit << endl << endl;
        out << "学期总数为:" << term_number << endl;
        out.close();
        cout << "教学计划已保存到文件--Finish the project short.txt中" << endl;
    }
}

菜单函数

//程序菜单
int Graph::Menu()
{
    int i;
    do {
        system("cls");
        cout << "***************教学计划编制系统****************" << endl << endl;
        cout << "           1.文件形式读入课程信息" << endl;
        cout << "           2.键盘形式读入课程信息" << endl;
        cout << "           3.课程信息修改" << endl;
        cout << "           4.课程信息输出" << endl;
        cout << "           5.按各学期中的学习负担尽量均匀地制定教学计划" << endl;
        cout << "           6.按尽可能短的时间完成学习制定教学计划" << endl;
        cout << "           7.退出程序" << endl << endl;
        cout << "********************************************" << endl << endl;
        cout << "           请输入您的选择:";
        cin >> i;

    } while (i < 1 || i>7);
    return i;
}

最后浅放两个图,因为要答辩,基本上把能想到的多写上去了,健全性还行,就是CLion感觉不太好用一样。

好了,继续写报告去了!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/932326.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号