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