oo 第三单元总结

本单元作业是完成社交关系模拟系统,可以通过各类输入指令来进行数据的增删查改等交互。

第一次作业

1、设计策略

本次作业主要需要实现Network,Person以及异常类。我先仔细阅读了JML规格,理解每一个方法的用途,对于一些方法的实现方式进行了思考。首先完成了异常类的处理,在此我设计了Counter类作为每一个异常类的static属性,用于记录触发异常的id和次数。接下来按照规格完成MyPerson的内容,最后完成了MyNetwork的内容。

2、容器选择

  • Network中选择HashMap存储人的信息,其中keypersonidvaluePerson
  • Network中选择HashMap存储每个人对应的祖先节点,其中Key保存personidvalue为对应的父节点的id
  • Person中选择HashMap进行存储,其中key为与该person关联的人的idvalue为二者的关联值。

3、性能问题

本次作业会出现性能问题的方法是isCirclequeryblocksum方法,对此我采用的是并查集+压缩路径的方法。

  • isCircle方法的功能是判断两者是否连通。在每次添加person时,将其对应的祖先节点设为自己,之后再在每一次添加关系时对该值进行修改。压缩路径是将所有在路径中的person的祖先节点都设为根节点。

    public void merge(int id1, int id2) {
        //每次添加关系时进行更改
            int father1 = find(id1);
            int father2 = find(id2);
            if (father1 == father2) {
                return;
            } else {
                father.replace(father1, id2);//两者不连通,将id2设为id1祖宗节点的father
            }
        }
    
    public int find(int id) {
            int root = id;
            while (root != this.father.get(root)) {
                root = this.father.get(root);
            }
            int path = id;
            int temp;
            while (path != root) {
                temp = father.get(path);
                father.replace(path, root);//压缩路径
                path = temp;
            }
            return root;
        }
    
  • queryblocksum方法的功能是查询连通分支数目,如果按照JML的方式实现会出现复杂度较高的情况。由于之前在添加关系时就对每个节点的祖先节点进行设置,所以只要一次遍历,其fatherid==id就是一个新的连通分支,这样是O(n)的复杂度。

第二次作业

1、设计策略

此次作业在上次作业的基础上增加了GroupMessage和四个异常类。对于四个异常类的处理方式与第一次作业相同,对于Group类的部分方法需要进行相应的思考(具体内容见下文),其余内容可以根据JML所描述的功能进行完成。我依旧是先完成异常类的处理,接下来完成比价容易的MyNetworkMyMessageMyPerson,最后完成相对复杂的MyGroup

2、容器选择

在第一次作业的基础上,增加了对于GroupMessage信息的存储。

  • Person中使用ArrayList保存Message;
  • Group中使用HashMap保存组内的人员idPerson;
  • NetWork中增加HashMap保存分组的idGroup;
  • NetWork中增加HashMap保存消息对应的idMessage

3、性能问题

在第二次作业中会涉及到的性能问题有Group中的getValueSum方法和getAgeMean方法。在这里需要注意复杂度和精度问题。我采用的策略是在MyGroup中设定相应的属性保存valuesumagevar。在向Group中加入人员时需要更新相应的存储值,其中value值要增加两倍。

第三次作业

1、设计策略

在第二次作业的基础上,此次作业增加了两个异常类,增加了EmojiMessageNoticeMessageRedEnvelopeMessage类。我先完成了异常类的内容,进而完成了各类的内容。

2、容器选择

本次作业在上次作业的基础上增加了信息的种类。

  • NetWork类中加入了HashMap保存表情信息,其中idemojiIdvalue是表情热度。

3、性能问题

本次作业主要存在性能的方法是sendIndirectMessage,这个方法主要是寻找最短路径,对此我采用的是堆优化的Dijkstra

测试的方法和策略

本单元作业主要利用对拍进行测试,在第三次作业的对拍中发现sendIndirectMessage方法中忘记了对isCircle的判断。

心得体会

这个单元让oo变得和善了许多~很欣慰的是本单元的三次作业的互测和强测中都没有出现bug。在本单元的学习中除了完成注意算法的复杂度外,还需要有在完成作业的过程中有耐心且细心,对于较长的规格要耐心阅读理解需要完成的内容,不能忽视JML中的每一个细节才能保证正确性。

posted @ 2021-05-28 11:18  祎yi  阅读(72)  评论(1)    收藏  举报