2020-2021-2学期课程分布情况分析

分析环境

Ubuntu18.04 LTS Server版本、C++11语言支持

课表课程分布分析

构建课表基本分布形态

Week[1]     1  2  3  4  5
Class[1]:      7     7   
Class[2]:   2  8 10  9 10
Class[3]:   3    11  8   
Class[4]:        12      
Class[5]:      9  2      


Week[2]     1  2  3  4  5
Class[1]:      7     7   
Class[2]:   2  8 10  9 10
Class[3]:   3    11  8   
Class[4]:        12      
Class[5]:      9  2      


Week[3]     1  2  3  4  5
Class[1]:      7     7   
Class[2]:   2  8 10  9 10
Class[3]:        11  8   
Class[4]:        12      
Class[5]:      9  2      


Week[4]     1  2  3  4  5
Class[1]:      7  4  7   
Class[2]:   2  8 10  9 10
Class[3]:   4    11  8   
Class[4]:   5    12      
Class[5]:   5  9  2      


Week[5]     1  2  3  4  5
Class[1]:      7  4  7   
Class[2]:   2  8 10  9 10
Class[3]:   4    11  8   
Class[4]:   5    12      
Class[5]:   5  9  2      


Week[6]     1  2  3  4  5
Class[1]:      7  4  7   
Class[2]:   2  8 10  9 10
Class[3]:   4    11  8   
Class[4]:   5    12      
Class[5]:   5  9  2      


Week[7]     1  2  3  4  5
Class[1]:      7  4  7   
Class[2]:   2  8 10  9 10
Class[3]:   4    11  8   
Class[4]:   5    12      
Class[5]:   5  9  2      


Week[8]     1  2  3  4  5
Class[1]:      7  4  7   
Class[2]:   2  8 10  9 10
Class[3]:   4    11  8   
Class[4]:   5    12      
Class[5]:   5  9  2      


Week[9]     1  2  3  4  5
Class[1]:      7  4  7   
Class[2]:   2  8 10  9 10
Class[3]:   4    11  8   
Class[4]:   5       13   
Class[5]:   5  9  2      


Week[10]    1  2  3  4  5
Class[1]:      7     7   
Class[2]:      8 10    10
Class[3]:        11  8   
Class[4]:           13   
Class[5]:                


Week[11]    1  2  3  4  5
Class[1]:   1  7     7  1
Class[2]:      8 10    10
Class[3]:        11  8   
Class[4]:           13   
Class[5]:   6     6      


Week[12]    1  2  3  4  5
Class[1]:   1  7     7  1
Class[2]:      8 10    10
Class[3]:        11  8   
Class[4]:           13   
Class[5]:   6     6      


Week[13]    1  2  3  4  5
Class[1]:   1  7     7  1
Class[2]:      8 10    10
Class[3]:        11  8   
Class[4]:                
Class[5]:   6     6      


Week[14]    1  2  3  4  5
Class[1]:   1  7     7  1
Class[2]:      8         
Class[3]:        11  8   
Class[4]:                
Class[5]:   6     6      


Week[15]    1  2  3  4  5
Class[1]:   1           1
Class[2]:                
Class[3]:        11      
Class[4]:                
Class[5]:   6     6      


Week[16]    1  2  3  4  5
Class[1]:   1           1
Class[2]:                
Class[3]:        11      
Class[4]:                
Class[5]:   6     6      


Week[17]    1  2  3  4  5
Class[1]:   1 14    15  1
Class[2]:     14 14 15   
Class[3]:   3    11    14
Class[4]:              14
Class[5]:   6     6      


Week[18]    1  2  3  4  5
Class[1]:   1 14    15  1
Class[2]:     14 14 15   
Class[3]:   3    11    14
Class[4]:              14
Class[5]:   6     6      


Week[19]    1  2  3  4  5
Class[1]:   1           1
Class[2]:                
Class[3]:                
Class[4]:                
Class[5]:   6     6      

计算周际差异

由于课程具有较为明显的区分度,下面将通过对比,筛选出具有明显分界变化的交接周。这些交接周是很有可能成为中间考试周的区域。

Def( 1, 2) =  0
Def( 2, 3) =  1
Def( 3, 4) =  4
Def( 4, 5) =  0
Def( 5, 6) =  0
Def( 6, 7) =  0
Def( 7, 8) =  0
Def( 8, 9) =  2
Def( 9,10) =  8 ==> Attention(前半学期结束)
Def(10,11) =  4
Def(11,12) =  0
Def(12,13) =  1
Def(13,14) =  2
Def(14,15) =  4
Def(15,16) =  0
Def(16,17) =  8 ==> Attention(实习大作业开始)
Def(17,18) =  0 
Def(18,19) =  9 ==> Attention(实习大作业结束)

学期按课程划分:

1、弱划分:1-9,10-16,17-18,19-20

2、强划分:1-3,4-9,10,11-14,15-16,17-18,19-20

空闲课程分布分析

对前19周的空闲课程进行综合统计

//全19周完全空闲课程
AllNum=19 @[day5-class5]
AllNum=19 @[day4-class5]
AllNum=19 @[day2-class3]
AllNum=19 @[day2-class4]

//具有高利用价值的空闲课程
AllNum=17 @[day5-class4]
AllNum=17 @[day5-class3]
AllNum=15 @[day4-class4]
AllNum=13 @[day1-class4]
AllNum=13 @[day3-class1]

//具有中等利用价值的空闲课程
AllNum=11 @[day3-class4]
AllNum=10 @[day1-class1]
AllNum=10 @[day2-class5]
AllNum=10 @[day5-class1]
AllNum=10 @[day1-class2]

//下面是 低空闲度 课程
AllNum= 9 @[day1-class3]
AllNum= 8 @[day4-class2]
AllNum= 6 @[day5-class2]
AllNum= 5 @[day4-class3]
AllNum= 4 @[day3-class2]
AllNum= 4 @[day1-class5]
AllNum= 3 @[day4-class1]
AllNum= 3 @[day2-class2]
AllNum= 3 @[day2-class1]
AllNum= 1 @[day3-class3]
AllNum= 1 @[day3-class5]

按弱划分进行空闲课程统计

弱划分:1-9,10-16,17-18,19-20
1-9周
AllNum= 9 @[day5-class5]
AllNum= 9 @[day5-class4]
AllNum= 9 @[day5-class3]
AllNum= 9 @[day5-class1]
AllNum= 9 @[day4-class5]
AllNum= 9 @[day2-class4]
AllNum= 9 @[day2-class3]
AllNum= 9 @[day1-class1]
---
AllNum= 8 @[day4-class4]
AllNum= 3 @[day3-class1]
AllNum= 3 @[day1-class5]
AllNum= 3 @[day1-class4]
AllNum= 1 @[day3-class4]
AllNum= 1 @[day1-class3]
10-16周
AllNum= 7 @[day1-class2]
AllNum= 7 @[day1-class3]
AllNum= 7 @[day1-class4]
AllNum= 7 @[day2-class3]
AllNum= 7 @[day2-class4]
AllNum= 7 @[day2-class5]
AllNum= 7 @[day3-class1]
AllNum= 7 @[day4-class2]
AllNum= 7 @[day4-class5]
AllNum= 7 @[day5-class3]
AllNum= 7 @[day5-class4]
AllNum= 7 @[day5-class5]
AllNum= 7 @[day3-class4]
---
AllNum= 4 @[day4-class4]
AllNum= 3 @[day3-class2]
AllNum= 3 @[day5-class2]
AllNum= 2 @[day4-class3]
AllNum= 2 @[day4-class1]
AllNum= 2 @[day2-class2]
AllNum= 2 @[day2-class1]
AllNum= 1 @[day3-class5]
AllNum= 1 @[day1-class1]
AllNum= 1 @[day5-class1]
AllNum= 1 @[day1-class5]
17-18周
AllNum= 2 @[day5-class5]
AllNum= 2 @[day5-class2]
AllNum= 2 @[day4-class5]
AllNum= 2 @[day4-class4]
AllNum= 2 @[day4-class3]
AllNum= 2 @[day3-class4]
AllNum= 2 @[day3-class1]
AllNum= 2 @[day2-class5]
AllNum= 2 @[day2-class4]
AllNum= 2 @[day2-class3]
AllNum= 2 @[day1-class4]
AllNum= 2 @[day1-class2]

综上所述,我们推荐在下述周期间的学习安排可以选择如下的时间段,我们可以保证每周在如下时间段中都可以自习。

格式:(工作日序号.第几节大课)

[1-9周]
(1.1),
(2.4),(2.3),
(4.5),
(5.1),(5.3),(5.4),(5.5)

[10-16周]
(1.2),(1.3),(1.4),
(2.3),(2.4),(2.5),
(3.1),(3.4),
(4.2),(4.5),
(5.3),(5.4),(5.5)

[17-18周]
(1.2),(1.4),
(2.3),(2.4),(2.5),
(3.1),(3.4),
(4.5),(4.4),(4.3),
(5.2),(5.5)

相关文件

分析使用的代码

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<fstream>
#include<queue>
#include<map>
#include<cstdio>
#define mem(s,value) memset(s,value,sizeof(s))
#define frein(s)  freopen(s,"r",stdin)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 1e5 + 10;

// #1.3
// 思想政治理论课综合实践
// 崔煜
// 1-2,17-18
// J1
// 323

/*存储信息使用的类*/

class Weeks{
public:
    int begin_week;
    int end_week;
    Weeks(int begin_,int end_):begin_week(begin_),end_week(end_){};
    Weeks(const string line){
        pair<int,int> p = parse(line);
        begin_week = p.first;
        end_week = p.second;
        // printf("[Weeks] %d-%d\n",begin_week,end_week);
    }

private:
    pair<int,int> parse(const string line){
        char* aim = new char[line.size()+3];
        memset(aim,0,sizeof(aim));
        memcpy(aim,line.c_str(),line.size());
        int a,b;
        sscanf(aim,"%d-%d",&a,&b);
        int sum = a + b;
        a = min(a,b);
        b = sum - a;
        // printf("%d %d\n",a,b);
        delete[] aim;
        // printf("delete[] ok\n");
        return make_pair(a,b);
    }

};

class Line{
public:
    int day;
    int classnum;
    string classpos;
    string classroom;

    //0123456789
    //1.3:J1-323
    //1.4:Js1-323
    //3.3:JB-排球67
    Line(const string line_info){
        // printf("line begin\n");
        string line = line_info;
        int lenth = line.size();
        if(lenth > 0)day = line[0] - '0';
        if(lenth > 2)classnum = line[2] - '0';
        classpos = "";
        int i = 4;
        for(;i<lenth && line[i]!='-';++i){
            classpos += line[i];
        }
        // printf("line flag1\n");
        classroom = "";
        if(i < lenth && line[i] == '-'){
            i++;
            while(i<lenth){
                classroom += line[i];
                i++;
            }
            // printf("line flag2\n");
        }
        // printf("line end\n");
        //完成解析
    }
};

class Info{
public:
    string classname;
    string teacher;
    vector<Weeks> WeekInfo;
    vector<Line> ClassInfo;

    Info(){};
    void addWeekInfo(Weeks rhs){
        WeekInfo.push_back(rhs);
    }
    void addClassInfo(Line rhs){
        ClassInfo.push_back(rhs);
    }

    //格式化信息
    string format(){
        string info = "#";
        //加入课程名
        info+=classname;
        info+='\n';
        //加入教师名
        info+=teacher;
        info+='\n';
        //加入周次信息
        for(int i=0;i<WeekInfo.size();i++){
            if(i)info+=',';
            Weeks& rhs = WeekInfo[i];
            info += inttostring(rhs.begin_week);
            info += '-';
            info += inttostring(rhs.end_week);
        }
        info+='\n';
        //加入课程信息
        for(int i=0;i<ClassInfo.size();i++){
            Line& rhs = ClassInfo[i];
            info += (rhs.day+'0');
            info += '.';
            info += (rhs.classnum+'0');
            info += ':';
            info += rhs.classpos;
            info += '-';
            info += rhs.classroom;
            info += '\n';
        }
        info += '\n';
        //返回结果
        return info;
    }
private:
    string inttostring(const int num){
        char* aim = new char[5];
        memset(aim,0,sizeof(aim));
        sprintf(aim,"%d",num);
        string line = string(aim);
        delete[] aim;
        return line;
    }

};


/*数据分析使用的类*/

class SumClass{
public:
    int class_day;//课程所在天
    int class_num;//节数序号
    int allnum;//出现次数

    SumClass(int d,int n,int allnum_){
        class_day = d;
        class_num = n;
        allnum = allnum_;
    }

    bool operator< (const SumClass& rhs)const{
        return allnum < rhs.allnum;
    }
};

//  Chart[周序号][日序号][节数序号] = 课程序号

//课程表格
int Chart[22][9][7];//编号从1开始,0不使用
//所有课程数量
int ClassNum = 0;
//存储课程信息
vector<Info> AllClass;
//课程序号映射
map<string,int> ClassMapper;

void addClassMapper();
int ReadInfo();
void fillClassChart();
int Defference(int wk1,int wk2);

int aim[30][30];
vector<SumClass> all;

//主函数
int main(int argc,char* argv[]){
    ReadInfo();//获取课程信息
    addClassMapper();//添加课程映射
    fillClassChart();//填充课程信息到表格

    // //进行课程分布形态对比
    // freopen("defference.txt","w",stdout);
    // for(int i=1;i+1<=19;i++){
    //     int week1 = i;
    //     int week2 = i+1;
    //     printf("Def(%2d,%2d) = %2d\n",week1,week2,Defference(week1,week2));
    // }

    //打印课表
    // freopen("chart.txt","w",stdout);
    // for(int week=1;week<=19;week++){//遍历周
    //     printf("Week[%d]     1  2  3  4  5\n",week);
    //     for(int i=1;i<=5;i++){//遍历每节课
    //         printf("Class[%d]: ",i);
    //         for(int day=1;day<=5;day++){//遍历天
    //             int p = Chart[week][day][i];
    //             if(p) printf("%3d",p);
    //             else printf("   ");
    //         }
    //         printf("\n");
    //     }
    //     printf("\n\n");
    // }
   
    //比较空信息
    //弱划分:1-9,10-16,17-18,19-20
    int per[2] = {17,18};
    for(int week=per[0];week<=per[1];week++){
        for(int day=1;day<=5;day++){
            for(int i=1;i<=5;i++){
                if(Chart[week][day][i] == 0){
                    aim[day][i]++;
                }
            }
        }
    }

    for(int day=1;day<=5;day++){
        for(int i=1;i<=5;i++){
            int t = aim[day][i];
            if(t){
                all.push_back(SumClass(day,i,t));
            }
        }
    }

    sort(all.begin(),all.end());
    // freopen("freeclass.txt","w",stdout);
    int len = all.size();
    int all_num = per[1] - per[0] + 1;
    int flag = 0;
    for(int i=len-1;i>=0;i--){
        SumClass& rhs = all[i];
        // printf("AllNum=%2d @[day%d-class%d]\n",rhs.allnum,rhs.class_day,rhs.class_num);
        if(rhs.allnum == all_num){
            if(flag++)printf(",");
            printf("(%d.%d)",rhs.class_day,rhs.class_num);
        }
    }
    printf("\n");
    return 0;
}




//生成可填充周序号列表
vector<int> generateWeeks(vector<Weeks>& rhs){
    vector<int> list;
    for(Weeks& pt : rhs){
        for(int i=pt.begin_week;i<=pt.end_week;i++){
            list.push_back(i);
        }
    }
    return list;
}


//填充课程数据表格
void fillClassChart(){
    for(int i=0;i<AllClass.size();i++){
        Info& rhs_info = AllClass[i];
        int class_num = ClassMapper[rhs_info.classname];
        for(int& week_num : generateWeeks(rhs_info.WeekInfo)){
            for(Line& rhs_line : rhs_info.ClassInfo){
                Chart[week_num][rhs_line.day][rhs_line.classnum] = class_num;
            }
        }
    }
}


//添加课程映射
void addClassMapper(){
    ClassMapper.clear();
    for(int i=0;i<AllClass.size();++i){
        Info& rhs = AllClass[i];
        ClassNum++;
        ClassMapper[rhs.classname] = ClassNum;
    }
}


//从myclass.txt中读取课程信息
int ReadInfo(){
    AllClass.clear();//清空
    ifstream inner;
    inner.open("myclass.txt",ios::in);
    string line;
    while(getline(inner,line)){
        // printf("====one====\n");
        int lenth = line.size();
        if(lenth < 1)continue;
        if(line[0] == '#'){
            Info oneinfo;
            //获取课程名
            string p = "";
            for(int i=1;i<lenth;i++)p+=line[i];
            oneinfo.classname = p;
            // cout << "classname: " << p << endl;
            //获取教师名称
            getline(inner,line);
            oneinfo.teacher = line;
            // cout << "teacher: " << line << endl;
            //获取课程周信息
            getline(inner,line);
            lenth = line.size();
            p = "";
            for(int i=0;i<lenth;i++){
                char ch = line[i];
                if(ch == ','){
                    oneinfo.addWeekInfo(Weeks(p));
                    p = "";
                }else{
                    p += ch;
                }
            }
            oneinfo.addWeekInfo(Weeks(p));
            // cout << "get week info" << endl;
            //获取课程位置信息
            while(1){
                //每两组课程信息之间必须存在至少一个空行
                getline(inner,line);
                // cout << "[" << line << "]" << endl;
                int lenth = line.size();
                if(lenth <= 0){
                    break;
                }else if(line[1]=='.'&&line[3]==':'){
                    oneinfo.addClassInfo(Line(line));
                }else{
                    break;
                }
            }
            //完成一次课程解析,存储起来
            AllClass.push_back(oneinfo);
        }//if(line[0]=='#')
    }//while
    inner.close();
    // //完成信息读入
    // //格式化输出
    // freopen("out.txt","w",stdout);
    // printf("==================================\n");
    // for(int i=0;i<AllClass.size();++i){
    //     cout << AllClass[i].format() << endl;
    // }
    return 0;
}


int Defference(int wk1,int wk2){
    int def = 0;
    for(int day=1;day<=5;day++){
        for(int i=1;i<=5;i++){
            if(Chart[wk1][day][i] != Chart[wk2][day][i])def++;
        }
    }
    return def;
}

输入用的课程信息文件myclass.txt

#物联网感知技术
罗汉江
11-19
1.1:J7-513
5.1:J7-504


#网络程序设计
赵建立
1-9
1.2:J7-313
3.5:J7-513


#思想政治理论课综合实践
崔煜
1-2,17-18
1.3:J1-323


#Java程序设计实验
仇丽青
4-9
1.3:J13-128
3.1:J13-128


#网络程序设计实验
赵建立
4-9
1.4:J13-128
1.5:J13-128


#单片机原理与应用
陈雪
11-19
1.5:J7-513
3.5:J7-513


#概率论与数理统计
张子叶
1-14
2.1:J5-308
4.1:J5-308

#毛概
周月
1-14
2.2:J1-407
4.3:J1-407


#Java程序设计
仇丽青
1-9
2.5:J7-313
4.2:J7-113


#计算机组成原理
傅游
1-13
3.2:J7-404
5.2:J7-304


#体育排球4-4
禚宝海
1-18
3.3:JB-排球67


#香港电影赏析与漫谈
戴宜雯
1-8
3.4:Js1-411


#形势与政策4-4
邱楚珈
9-12
4.4:J1-221


#物联网感知技术实验
罗汉江
17-18
2.1:J13-128
2.2:J13-128
3.2:J13-128
5.3:J13-128
5.4:J13-128


#物联网感知实习
于建志
17-18
4.1:J13-128
4.2:J13-128
6.1:J13-128
6.2:J13-128
6.3:J13-128
6.4:J13-128
6.5:J13-128
7.1:J13-128
7.2:J13-128
7.3:J13-128
7.4:J13-128
7.5:J13-128

注:毛概课程因敏感词汇只能简写。

OK

posted @ 2021-02-28 23:19  SavenNeer  阅读(104)  评论(0编辑  收藏  举报