软件工程实践2017第二次结对做业

结对成员

031502643 朱晓健
031502626 孙浩楷git

GitHub项目地址

用力戳我程序员

数据生成程序

input_data.txt
数据主要采用rand()来随机生成。经过相关措施来防止随机生成的重复数据,而后用Jsoncpp的Json::Writer输出。github

考虑因素

  • 部门总数为20个,学生总数为300个
  • 时间段必须具备实际意义
  • 防止部门号和学生号重复
  • 做业要求中的其余点均要知足
    在咱们写数据生成程序的时候,遇到了生成的学号超过规定长度的状况,后来发现是一个地方过于粗心,没有对字符串清空。还有就是为了让unlucky_student和unlucky_department的数量尽可能少,咱们的free_time时间段是设的比较多的,event_schedule时间段是设的比较少的,但都知足两个以上的基本要求。

匹配程序

前序

看到题目的时候原本想直接从文本读入数据而后进行符号的识别与筛选,后来在上课的时候听到旁边两个同窗正在讨论此次的结对做业,依稀听到了什么JSON格式输入很方便啊(内心一阵窃喜hahaha),虽然不知道JSON是什么,不过应该对此次的结对做业有帮助。
下课回去后,又认真地看了下题目,发现题目里赫然写着“Json格式”,若是我没猜错的话,我第一步要完成的工做应该就是把JSON格式的数据读到C++程序中。上网百度了一下须要安装jsoncpp,按照网上的教程死活装不上去,一直提示“link2005“”重定义错误,气的我有种砸电脑的冲动,折腾了我一早上。后来是在MSDN上看到的解决办法,在连接器的命令行中加入“ /FORCE:MULTIPLE ”,终于TM能用了。算法

数据建模

Student类的私有数据student_no,tags采用string类型,application_department采用动态string数组指针,并在析构函数中释放所申请的堆内存,free_time和department_no采用vector容器来存储。Department类的私有数据department_no,tags采用string类型,event_schedules采用动态string数组指针,member采用vector容器来存储。Student类和Department类互为友元类,方便成员函数的数据访问。编程

匹配程序思路

首先根据学生的部门意愿顺序来匹配,只要该学生的一个空闲时间段和该部门一个常规活动时间段匹配,该学生就能加入到该部门中;而后,再对全部部门进行扫描,若是发现部门人数超过限制人数的,则剔除兴趣标签不匹配的学生,直到部门人数等于限制人数为止,若是兴趣标签不匹配的学生都剔除完了部门人数仍然超过限制人数,则随机剔除,直到部门人数等于限制人数为止;对被剔除的学生再进行一次部门时间段匹配,以保证尽量多的学生能分配到部门。json

实现方式

  • 首先利用Json::Reader将txt的字符流转换成Json::Value
  • 使用函数Student::StuAssignment和Department::DepAssignment将Json::Value数据读入到各自的类私有数据中。
  • 按照匹配原则使用Student::TimeMatch进行学生空闲时间段和部门常规活动时间段的匹配,匹配成功则加入该部门,并删除新成员相应的free_time,防止和后续的意愿部门时间冲突。
  • 扫描每一个部门的人数,若超过限制人数,则使用Department::InterestFilter函数对部门成员进行剔除,优先剔除兴趣标签不匹配的,直到人数等于限制人数,对被剔除的学生归还相应的free_time。
  • 对被剔除的学生使用Student::Redistribute函数调用Student::TimeMatch函数进行匹配。
  • 将相关数据写入Json::Value,使用Json::StyledWriter转换成字符流并输出。数组

    写匹配程序时遇到的一些问题

  • 原本是不想将两个类弄成互为友元类的,可是若是使用友元成员函数的话会引发循环依赖问题致使报错,在网上搜索了相关的解决方法并无找到,只能声明为友元类了。
  • 在最后的结果输出时,遇到了一点麻烦,示例中的输出是按照(unlucky_student,admitted,unlucky_department)的顺序进行输出的,可是个人程序不论怎么改,死活是按照(admitted,unlucky_department,unlucky_student)的顺序输出。在网上找了很久,后来发现由于jsoncpp是基于map容器,而map的key是按照字母顺序进行索引,若是要修改的话,要改STL,并且会致使map的算法效率降低。在咨询了助教以后,得知不按顺序也是能够的,因而便放弃了修改STL的想法。app

代码规范

采用类来封装数据。变量名主要采用小写字母构成,单词与单词之间用下划线链接;函数名采用字母构成,单词首字母大写,单词之间没有使用分隔符。以Student类为例:函数

class Student
{
private:
    std::string student_no;
    std::vector<std::string>free_time;
    int freetimes;
    std::string *applications_department;
    int applications;
    std::string tags;
    std::vector<std::string>department_no;
    friend class Department;
public:
    Student();
    ~Student();
    void StuAssignment(Json::Value &root, int index);//将json数据读到Student类中
    void TimeMatch(Department*dep,bool check);//进行时间匹配
    bool UnluckyStudents();//判断一个学生是否一个部门都没被分配到
    void FreetimeDelete(Department&dep);//对已分配到部门的学生删除相应的free_time
    void Redistribute(Department&dep,Department*deps);//对被踢出的学生进行从新分配
    friend int GetIndex(Student*stu, Department*dep, std::string s);//由部门号或者学生号获取索引
};

结果评估

按照上述的匹配原则,以示例中input_data.txt为例的话,有126个unluncky_student,0个unlucky_department。本次匹配原则并无很是地严苛,只要学生空闲时间里的一个与部门活动时间段匹配即算匹配成功,所以unlucky_student相较于全匹配原则减小了不少。对匹配结果基本满意。工具

尤为是最后一个对被踢出的学生按照其部门意愿再进行分配我以为颇有必要,这样可以最大程度的保证每一个学生能分配到部门。固然,若是空闲时间老是不和部门活动时间相匹配的话也只能成为UnluckyStudent了。

结对感觉

此次的做业恰逢国庆,我回家了,浩楷在学校,没法面对面地进行交流,所以采用聊天工具QQ进行沟通。咱们轮流进行编程,虽然没能出去玩,可是感受这个国庆过得很充实。从浩楷身上学到不少项目经验。结对项目做业使我学到不少合做的经验,而且提升了我与人沟通交流的能力,使我受益不浅,对我未来成为一个合格的程序员有很大帮助。虽然累了点,可是并不后悔当初选了软工实践这门课,到目前为止我真的学到了不少,这是之前其余课程所不能带给个人。

相关文章
相关标签/搜索