第六次作业--结对编程第二次
结对情况
队友 225 方宜
自己 223 盛
码云项目链接
设计说明
类图
接口设计(API)
public system
{
public Json::Value project(Json::Value root)//处理数据
public Json::Value read(std::string filename)从文件中读取数据
public void put(Json::Value root)向文件输出数据
}
匹配算法:
鉴于整个程序全部由我一个人完成并且花费了大量的时间在逼迫队友进行编码上。。所以算法相当简单粗暴:
首先将数据读入,通过类数组进行存储,再另外存储学生的编号与其绩点排名的关系,即将学生数根据绩点进行排名,然后进行学生与社团的匹配,绩点高的学生优先,在根据时间确定能够进入该社团之后删除学生数据中活动时间与社团活动时间重叠的部分,然后进行下一次匹配
测试数据如何生成:
测试数据生成程序的部分代码如下:
int main()
{
srand(time(NULL));
int a, b, i, j;
std::string weeks[7] = { ... };
std::string tags[50] = {...};
Json::Value root;
Json::Value next;
Json::Reader reader;
Json::FastWriter fwriter;
Json::StyledWriter swriter;
char department_name_a[6];
char department_no_a[4];
srand(time(NULL));
cin >> a >> b;
std::string name[100];
for (i = 0;i < a;i++) {
...
next["department_no"] = Json::Value("FZU_"+department_no_b);
next["department_name"] = Json::Value("abc"+ department_name_b);
next["member_limit"]=Json::Value(rand() % 16);
int k[8] = {60}; //记录是否出现重复的tags;
int e;
for (j = rand() % 8;j >= 0;j--) {
k[7 - j] = rand()%50;
for (e = 7 - j;e < 7;e++) {
if (k[7 - j] == k[e] && 7 - j != e) {
e = 8;
break;
}
}
if (e == 8) {
continue;
}
next["tags"].append(tags[k[7-j]]);
}
for (j = rand() % 3 + 1;j > 0;j--) {
...
next["event_schedules"].append(weeks[(rand() % 2 + 1 + (5 - j)) % 7] + timest + ":00--" + timeen + ":00" );
}
for (j = 0;j < 8;j++) {
k[j] = 80;
}
root["departments"].append(next);
next.clear();
}
char student_no[6] = { '0' };
char student_nam[6] = { '0' };
for (i = 0;i < b;i++) {
...
next["student_no"] = student_n;
...
next["student_name"] = student_name;
int k[8] = { 60 }; //记录是否出现重复的tags;
int e;
for (j = rand() % 8;j >= 0;j--) {
k[7 - j] = rand() % 50;
for (e = 7 - j;e >=0;e--) {
if (k[7 - j] == k[e] && 7 - j != e) {
e = 8;
break;
}
}
if (e == 8) {
continue;
}
next["tags"].append(tags[k[7 - j]]);
}
for (j = 0;j < 8;j++) {
k[j] = 200;
}
for (j = rand() % 5 + 3;j > 0;j--) {
char timestart[3];
int ran = rand() % 15 + 7;
...
std::string timest = (×tart[0]);
char timeend[3];
int en = ran + (rand() % 3 + 1);
...
std::string timeen = (&timeend[0]);
next["available_schedules"].append(weeks[(rand() % 2 + 1 + (7 - j)) % 7] + timest + ":00--" + timeen + ":00");
}
for (j = rand() % 5; j >= 0; j--) {
k[5 - j] = rand() % a;
for (e = 5 - j; e >= 0; e--) {
if (k[5 - j] == k[e] && 5 - j != e) {
e = 8;
break;
}
}
if (e == 8) {
continue;
}
next["want_departments"].append(name[k[5 - j]]);
}
int gpa ;
gpa = rand() %100;
next["GPA"]=(gpa);
gpa = 0;
root["students"].append(next);
next.clear();
}
...
ofs.open("s" + title1 + "-d" + title2 + "-in.json");
ofs << swriter.write(root);
ofs.close();
return 0;
}
如何评价自己的匹配算法
和自己当初打算实现的算法相差还是蛮大的,但是由于自身时间不够,所以就只赶时间做出了这样一个完全暴力的算法,首先时间判断部分只要部门活动时间只要在学生空闲时间里就会直接删除学生该段时间,会导致学生不能加入另外一些部门,另外就是基本没有给绩点低的同学机会,会导致绩点高的同学加入了超多的部门而绩点低的同学没部门可加
关键代码解释
for (i = 0; i < b; i++) {
c = students[f[i]].want_num;
for (j = 0; j < c; j++) {
department[students[f[i]].want_department[j]];
if (department[students[f[i]].want_department[j]].member_limit > department[students[f[i]].want_department[j]].num_member) { //还有空位的情况下
cout << 10;
d = 0;
e = 0;
for (k = 0; k < department[students[f[i]].want_department[j]].event_num; k++) {
for (l = 0; l < students[f[i]].available_num; l++) {
if (students[f[i]].available_schedules[l][0] == department[students[f[i]].want_department[j]].event_schedules[k][0]) {
if (students[f[i]].available_schedules[l][1] <= department[students[f[i]].want_department[j]].event_schedules[k][1]) {
if (students[f[i]].available_schedules[l][2] >= department[students[f[i]].want_department[j]].event_schedules[k][2]) {
break;
}
}
}
}
if (l == students[f[i]].available_num) {
d = d + 1;
if (d >2) {
e = 1;
break;
}
}
}
if (e == 1) {
}
else {
for (k = 0; k < department[students[f[i]].want_department[j]].event_num; k++) {
for (l = 0; l < students[f[i]].available_num; l++) {
if (students[f[i]].available_schedules[l][0] == department[students[f[i]].want_department[j]].event_schedules[k][0]) {
if (students[f[i]].available_schedules[l][1] <= department[students[f[i]].want_department[j]].event_schedules[k][1]) {
if (students[f[i]].available_schedules[l][2] >= department[students[f[i]].want_department[j]].event_schedules[k][2]) {
students[f[i]].available_schedules[l][2] = students[f[i]].available_schedules[l][1]; //学生的一个活动时间只允许参加一个部门项目;
break;
}
}
}
}
}
students[f[i]].whatin[students[f[i]].num_in] = students[f[i]].want_department[j]; //将部门记入学生
department[students[f[i]].want_department[j]].member[department[students[f[i]].want_department[j]].num_member] = f[i]; //将学生记入部门
department[students[f[i]].want_department[j]].num_member++; //部门成员数++
students[f[i]].num_in++; //学生入部数++
}
}
}
}
关键代码就只放出了关于学生时间与部门活动时间的匹配部分的代码
运行及测试结果展示
以下测试数据均在项目内的tests文件夹内
200位同学,20个部门的情况
输入:
{
"departments" : [
{
"department_name" : "abcabnjo",
"department_no" : "FZU_000",
"event_schedules" : [ "Sun18:00--19:00" ],
"member_limit" : 8,
"tags" : [ "azmrn", "hcbsx", "ffscx", "racbw" ]
},
{
"department_name" : "abcbpdti",
"department_no" : "FZU_001",
"event_schedules" : [ "Fri20:00--22:00", "Sun07:00--09:00" ],
"member_limit" : 9,
"tags" : [ "zyxab", "ajymm", "xwzjc", "zyxab", "nhyng", "dtzau" ]
},
{
...
输出:
{
"department_no_students" :
[
{
"department_name" : "abcthyxt",
"department_no" : "FZU_019"
}
],
"department_with_students" :
[
{
"department_name" : "abcabnjo",
"department_no" : "FZU_000",
"department_students" :
[
{
"student_name" : "RZODH",
"student_no" : 15
},
{
"student_name" : "FOZXM",
"student_no" : 3
},
.....
]
}
[
...
500位同学,30个部门的情况
输出:
{
"department_no_students" :
[
{
"department_name" : "abcizhvt",
"department_no" : "FZU_008"
},
{
"department_name" : "abcqjiba",
"department_no" : "FZU_016"
},
{
"department_name" : "abcrpylu",
"department_no" : "FZU_017"
},
{
"department_name" : "abcszmfa",
"department_no" : "FZU_018"
},
{
"department_name" : "abcutnhy",
"department_no" : "FZU_020"
},
{
"department_name" : "abcvfupu",
"department_no" : "FZU_021"
},
{
"department_name" : "abcdjbbw",
"department_no" : "FZU_029"
}
],
...
1000位同学,50个部门的情况
{
"department_no_students" :
[
{
"department_name" : "abchnena",
"department_no" : "FZU_007"
},
{
"department_name" : "abclhxnf",
"department_no" : "FZU_011"
},
{
"department_name" : "abctnvdk",
"department_no" : "FZU_045"
}
],
"department_with_students" :
[
{
"department_name" : "abcaxqza",
"department_no" : "FZU_000",
"department_students" :
[
{
"student_name" : "DTBMI",
"student_no" : 40
},
...
5000位同学,100个部门的情况
{
"department_no_students" :
[
{
"department_name" : "abcphmzy",
"department_no" : "FZU_015"
},
{
"department_name" : "abcsfjjk",
"department_no" : "FZU_018"
},
{
"department_name" : "abctnirt",
"department_no" : "FZU_045"
},
{
"department_name" : "abcgzjbh",
"department_no" : "FZU_084"
},
{
"department_name" : "abcmxlrv",
"department_no" : "FZU_090"
}
],
"department_with_students" :
[
{
"department_name" : "abcarafo",
"department_no" : "FZU_000",
"department_students" :
[
{
"student_name" : "YWDRY",
"student_no" : 236
},
...
遇到的困难及解决方法
首先是jsoncpp的配置
解决办法:我们宿舍三个人查了6个小时的百度,谷歌以及各种论坛最后瞎改配置就能编译成功了。
然后就是队友不管怎么催他都不写作业,然后我以我不干了去逼他他就配置了个环境然后再没开过vs
这个困难并没有被解决,所以最后我赶工赶出来的代码才会这么糙......
收获:
有个好队友很重要
对队友的评价
很满意
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 10 |
· Estimate | · 估计这个任务需要多少时间 | 100 | 80 |
Development | 开发 | 10 | 60 |
· Analysis | · 需求分析 (包括学习新技术) | 60 | 60 |
· Design Spec | · 生成设计文档 | 5 | 5 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 5 | 5 |
· Design | · 具体设计 | 10 | 10 |
· Coding | · 具体编码 | 500 | 300 |
· Code Review | · 代码复审 | 0 | 0 |
· Test | · 测试(自我测试,修改代码,提交修改) | 0 | 0 |
Reporting | 报告 | 60 | 60 |
· Test Report | · 测试报告 | 30 | 15 |
· Size Measurement | · 计算工作量 | 5 | 5 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 5 | 30 |
合计 | 810 | 670 |
8.学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 120 | 120 | 24 | 24 | 学会很多小技巧,命令行传参,输出到文件之类 |
2-3 | 0 | 0 | 8 | 32 | 看了课本的第4,8章,学习了原型的设计方法 |
5 | 100 | 220 | 5 | 37 | 向队友学习了很多 |