首页 > 其他 > 详细

OO第三单元总结

时间:2021-06-02 00:02:51      阅读:18      评论:0      收藏:0      [点我收藏+]

OO第三单元总结

(1)实现规格要求所采取的设计策略

MyMessage,MyEmojiMessage,MyNoticeMessage,MyRedEnvelopeMessage按照指导书要求实现构造方法,随后实现相应的get(),set()方法和equal()方法即可。

Main函数按照指导书给出的实现即可。

MyPerson除了需要实现的属性,使用了四个容器来实现相应的操作

private LinkedList<Message> messages;
//记录接收到的message,使用LinkedList方便实现规格要求的在所有Message的头部插入
private HashMap<Integer, MyPerson> acquaintanceMap;
//记录这个Person和那些Person相连,key表示连接到的Person的id,value表示相应的Person
private HashMap<Integer, Integer> valueMap;
//记录和这个Person相连的Person的边的value,key表示连接到的Person的id,value表示相应边的value值
//经过分析发现,其实可以把这两个HashMap合成一个,key值代表连接的Person的id,value代表这条边的value值
private HashMap<Integer, Group> inGroup;
//记录这个Person在那些Group中,key表示Group的id,value代表相应的Group,用于优化MyGroup的getValueSum()方法

一些方法的实现策略:

  • addRelation()除了要在acquaintanceMap和valueMap中增加相应的key-value值,还需要把Person所在的Group的valueSum增加这条边的value值
  • 除规格要求的方法外,还实现了
    • addAtHead()增加收到的Message
    • addInGroup()增加Person所在的Group,Group中addPerson()时调用
    • removeInGroup()减少Person所在的Group,Group中delPerson()时调用

MyGroup除了需要实现的属性,使用了一个容器来实现相应的操作

private HashMap<Integer, Person> people;
//记录Group中包含那些人,key表示Person的id,value表示相应的Person

一些方法的实现策略:

  • 为了实现O(1)的getValueSum()和getAgeMean(),每次加入/删除Person的时候动态更新ageSum,而valueSum除了需要在加入/删除Person的时候更新,还需要在增加一条边的时候更新,因此,在Person中定义了inGroup(),方便动态更新。

MyNetwork使用如下方法来实现规格

private HashMap<Integer, Person> personMap;
//记录Network中包含那些人,key表示Person的id,value表示相应的Person
private HashMap<Integer, Integer> root;
//并查集的根数组,因为id范围并非从0或1开始的连续整数,可以选择离散化或者使用HashMap直接代替数组,在冲突不多的条件下,可以认为HashMap的查询是O(1)的,和数组并没有很大的时间效率上的差距。
private int blockNum;
//记录连通块的个数
private HashMap<Integer, Group> groupById;
//记录Network中的Group,key表示Group的id,value表示相应的Group
private HashMap<Integer, Message> messageById;
//记录所有Message,Key表示Message的id,value表示相应的Message
private HashMap<Integer, Integer> emojiById;
//EmojiMessage按emojiId分类,value值选择hashmap方便删除

一些方法的实现策略:

  • isCircle(),queryBlockSum()为较快的实现,使用并查集,可以加边的同时,维护一个blockSum记录连通块的个数
  • sendIndirectMessage()使用堆优化的Dijkstra算法来计算最短路,时间复杂度为O((m+n)logn)

任一级中的contain方法均可以通过HashMap的contains。

(2)结合课程内容,整理基于JML规格来设计测试的方法和策略
  • 首先在基本了解JML语法的基础上,通读JML规格,了解规格希望实现的内容,主要是相应的方法和需要支持的查询方式。
  • 考虑数据范围和时间,选择可以在给定时间内完成查询的实现方法,实际上整体上只要选用了合适的容器,只有几个方法需要去考虑如何优化,其余方法直接调用容器的相应方法即可实现。
  • 理解相应类的包含关系,实现规格定义的方法。
(3)总结分析容器选择和使用的经验
  • 除了存储Person接收的Message之外全部采用的HashMap。
  • Person中记录此Person接收的Message采用LinkedList因为要支持在头部插入,采用链表可以很方便的实现。
  • 其他情况均选择HashMap因为HashMap可以以很快的效率实现增,删,查,改,这也是本次OO作业主要需要实现的功能,通过建立id到自身的HashMap可以很快的查找某一类的实例,从而实现规格所要求的方法。
(4)针对本单元容易出现的性能问题,总结分析原因
  • isCircle(),queryBlockSum()不能每次都按照相应的定义去查,使用并查集,来判断两个节点上是否存在联通路,然后在添加边的时候,动态维护一个int blockNum,保存连通块的个数即可
  • Group中的getValueSum(),getAgeMean()为了提高最坏情况下的时间效率,采用了O(n)的添加/删除和O(1)的查询,而不是O(1)的插入/删除和O($n^2$)的查询,在查询不太多的情况下(比如添加n个人查询1次),二者的摊还时间基本一致,但是当查询的比重变多时,前者有明显的时间效率的优势
  • sendIndirectMessage()中需要计算最短路,使用堆优化的Dijkstra算法,时间复杂度为O((m+n)logn),堆优化时使用java自带的优先队列存储自定义的Edge类的对象,表示当前到某个点的最短距离。
(5)梳理自己的作业架构设计,特别是图模型构建与维护策略

Network中包含Person,Group,每个Group中又包含相应的Person,可以认为把一个无向图分成了很多组,每一组就是一个Group

第三次作业的UML类图如下(选择MyMessage,MyPerson,MyGroup,MyNetwork画出相应类图)

技术分享图片

OO第三单元总结

原文:https://www.cnblogs.com/start0916/p/14838683.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!