结队成员介绍:
031502644——邹星
031502630——吴松青Github项目链接:
"数据生成程序"程序原理:
首先是初始化时间分配的数组,day包括七天(周一到周天),hour只包括8:00-22:00(考虑到不宜太晚出门,通宵等),而兴趣标签就取模板中的几个。
其次是写几个工具函数,方便后面的操作,比如部门初始化函数用于初始化部门的编,然后使用getId函数,用来随机生成学生的学号,且用标记的方法来确定是唯一的编号(如Sxxxxxx),最后写一个生成随机时间的函数,使用flag数组来标记是否生成的随机时间重复。
第三步就是部门与学生各自的初始数据生成的函数,首先是部门方面这里的话我们的想法是通过使用随机数来生成活动时间最后决定随机范围在2-5(感觉不宜太多,5个很多了,还是学习重要)。再生成一个10-15的随机数代表部门纳新数。然后生成2-9的部门标签数(有些部门可能很全面)就这样生成20组部门的数据。学生部分也是差不多如此,不同的就是标签必须取部门中有的,在这方面,用了一个标记数组标记该标签是否被部门使用过,若没有,则不添加给学生,这里学生的标签也就设置了2-6个(一般不会有很多兴趣,也方便之后的筛选),还有一点,学生的空闲时间设置的比部门多,毕竟考虑到学生可不只参加一个部门的活动。
最“好”的数据:
“匹配程序”的思路及实现方式:
输入和储存数据:
首先是导入要输入的数据,这里我们采用的是通过使用JSON格式来获取我们的input_data.txt中的数据。(这里有个小插曲,一开始我们使用txt的逐行输入,但在后来看到微信上同学的询问后才知道可以用json,于是紧急修改代码,也是很累啊!)而存储数据时,学生数据和部门数据分为不同的类:Student和Department。这里我们采用了动态数组的方法去存储活动时间,兴趣标签和学生对于自己的部门志愿这三种数据,其余数据则是用string和整型数组或者整型变量来存储。
匹配方法:
刚开始进行分配的时候可以知道的是学生的数量应该是会比部门多的。于是通过扫描学生来进行匹配。通过提取学生的一个志愿部门编号,再把编号放到部门数组中去寻找相应的部门。找到了该部门后,首先先检查自己是否已经有了以被纳入的部门,如果有的话,则先对自己以纳入的部门和该部门进行活动时间冲突检查,如果有冲突,由于部门意愿可是按照优先级从高到底的顺序排序的,所以已纳入的部门一定是优先级高于现在进行匹配的部门,于是跳过该名学生对此部门的匹配。如果没有冲突或者尚未被纳入部门中,则进行对该部门的检验。这里有几种情况:
1.当找到该部门后,发现该部门的纳入人数为0。此时则直接将该名学生纳入此部门。 2.当找到该部门后,发现该部门已经有纳入但人数还没满。此时则将该名学生与已纳入的学生进行排序。排序标准是兴趣标签优先,其次为活动时间。将兴趣标签符合的数目最小的学生排到数组末尾。如果两个学生兴趣标签数目相同,则再进行活动时间比较,将活动时间符合数目较小的学生排到数组后方。这样就能保证部门的纳入人员数组的最末尾的学生一定是最为不适合该部门的学生。 3.当找到该部门后,发现该部门已经有纳入而且纳入人数已满。此时则将该名学生与该部门的已纳入人员数组的末尾学生进行比较。比较方法和排序的标准一致。以兴趣标签优先,其次为活动时间。如果该学生更为“适合”该部门,则将该名学生替换末尾的那名相对不“适合”的学生。并且重新为新加入的学生进行排序,找到其相应的数组中的位置。 4.当找到该部门后,发现该部门已经有纳入而且纳入人数已满。此时则将该名学生与该部门的已纳入人员数组的末尾学生进行比较。发现该学生相较于该部门已纳入人员的末尾的那名学生来说更为不适合。则跳过该名学生对此部门的匹配。输出数据:
对于输出数据来说,则是按照例子中的output的输出格式输出到txt中。
代码规范:
代码风格:
1.缩进:缩进以Tab为单位,语句块的“{”“}”配对对齐,并与其前一行对齐,语句块类的语句缩进每个“}”单独占一行。 2.对齐:原则上关系密切的行应对齐,对齐包括类型、修饰、名称、参数等各部分对齐。 3.命名规范:命名尽量用英文简写或者首字母。
部分关键代码佐证:
string depId[21]; // 记录20个部门的编号string day[7] = { "Mon", "Tues", "Wed", "Thur","Fri", "Sat", "Sun"}; string hour[24] = { "08","09","10","11","12","13", "14", "15", "16","17", "18","19", "20","21","22"};string tags[10] = { "basketball","dance","chess","English","film","football","music","programming","reading","study" };mapid; // 检查编号是否重复bool flag[7][20]; //避免时间产生交集bool used_d[maxn]; // 记录被使用的部门编号bool used[maxn]; // 记录被使用的标签// --------------------- 随机生成唯一的学号 SXXXXXX ------------------string getId(string x){ string s_id = x; do { for (int i = 0; i < 6; i++) { s_id = s_id + to_string(rand() % 10) ; } } while (id[s_id]); id[s_id] = true; return s_id;}
结果评估:
将助教发布的例子用来测试,得到的结果是有几十名同学落选,然后每个部门都收入了人员,其中大部分都是收入了满足的人数。就这点来说,和我们的预想的情况是比较一致的。同时也是和现实中的部门纳新结果是比较符合的。但是同样也有一些问题我们并未来得及去考虑,首先就是一旦纳入了优先级较高的部门,万一发生了部门活动时间冲突的情况,必须否决了优先级低的部门的匹配,而此时又发生了此学生被部门所淘汰的情况时。是可以对原本活动时间冲突了被否决了的部门进行匹配检查的。但是由于时间问题,同时也是在后期我们才发现这个问题。所以并没有解决这个问题。其次是,如果以我们自己的生成的例子用来测试的话结果就不尽如人意,可能是生成的数据不怎么好吧。我认为是因为过于随机生成数据所以结果自然也不怎么会好看,哈哈。
结队感想:
额,毕竟当初是选择同班的进行结队,好处还是很多的。有了第一次结队的经验,我们对能在一起面对面讨论和一起进行代码编写上进行了调整。也正好我们国庆节也是大部分时间都是在学校的安排。所以能一起进行代码编写的时间也变得很多。在这里,也十分感谢我的结队队友,他对于c++上的一些函数运用的经验明显比我丰富得多,很多情况下,少写了很多无用的代码,也是让我学会了一些以前不知道的c++函数。同时也是,他针对我的一些算法的漏洞给指了出来,比如进行对比活动时间是否冲突的算法,也是他看出来了我的算法存在的一些问题所在。但是同时问题也是存在的,首先,两个人的代码风格不统一,有时候我写出来的代码他看起来会很“累”,就会叫我改一下,但是我又感觉改了以后我会很不舒服,这种情况经常出现。除了优点和缺点,还是有很多遗憾吧,总是感觉这次的作业没有我想象中完美,但是本身这也是一个很难抉择的问题,这次的作业选在国庆,着实是很刁钻,想要做得更加完美,则必须牺牲时间来钻研,而同样,我们搞出来初步的程序时,国庆也已经过了一大半了。所以也是十分无奈。也是在后期的时候我们才发现了数据输入的问题,临时加工把输入从txt逐行输入改成了json格式输入,也是临时赶工啊.....说到底,结队起来还是很有意思和意义的,二个人和一个人一起打代码的感觉完全不一样,既有新鲜感和好处优点,同时也会让我感觉到两个人一起的不适感。总得来说还是有得有失吧。会让我感觉到两个人一起的不适感。总得来说还是有得有失吧。