BUAA_OO 第三单元总结

目录

一、总结分析自己实现规格要求所采取的设计策略

首先分析要抛出哪些异常情况,把异常情况都抛完了再处理正常情况。

先通过JML读懂这个函数要实现什么功能,然后考虑有没有时间复杂度更优的实现方法。

二、基于JML规格来设计测试的方法和策略

JUnit:JUnit是一个开放源代码的Java测试框架,用于编写和运行可重复的测试。

OpenJML:OpenJML能够检查代码是否符合JML规范。最基本的功能就是对JML注释的完整性进行检查。可以对规格内容进行检查也可以执行运行时检查。

JMLUnitNG:JMLUnitNG是用于带有JML注释的Java代码的自动化单元测试生成工具。

和同学对拍。

三、容器选择和使用的经验

键值对用HashMap存储,单次操作复杂度为常数。

集合用HashSet存储。

有固定顺序的内容用ArrayList存储。

优先队列PriorityQueue

\\Network
private Map<Integer, Person> people;
private Map<Integer, Group> groups;
private Map<Integer, Message> messages;
private Map<Integer, Integer> emojiIdList;
\\Person
private Map<Integer, Edge> acquintance;
private List<Message> messages = new ArrayList<>();
\\Group
private Map<Integer, Person> people;
\\Dijkstra
Queue<HeapNode> q = new PriorityQueue<>();
Map<Integer, Integer> d = new HashMap<>();
Set<Integer> vis = new HashSet<>();

四、性能问题的总结与分析

分析几个重要的操作,自己能想到的比较好的复杂度做法,但是有些并没有去实现。

query_name_rank
可以用平衡树维护所有人的名字,插入O(logn),查询O(logn);
query_circle
路径压缩、按秩合并并查集维护,加边和查询“几乎”常数复杂度。
如果不按秩合并,则数据再大一点点就有爆栈的危险。
query_block_sum
若并查集合并操作,则连通块个数-1,O(1)
query_group_value_sum
atg和dfg时计算,枚举与这个点相连的边,判断另一点是否在Group内。更新O(n),查询O(1)
或者每次查询时枚举每个点,再枚举出边,单次O(n+m)

听@cjy说了一个n*sqrt(n)的做法,但是地方太小写不下了。
query_group_age_mean
关键在求Age的和,atg和dfg时O(1)维护,O(1)查询答案
query_group_age_var
求方差,关键在求\sum (x-t)^2 =(\sum x^2)-2t (\sum x)+ n*t^2
\sum x^2 和\sum x维护同qgam
n为人数,t为平均值。
atg和dfg时O(1)维护,O(1)查询答案

delete_cold_emoji
采用支持删除的小根堆(可以用双堆实现),每次检查堆顶是否可以删除,直到堆顶不能删,能删就查找这个表情对应的Message并删掉Message。复杂度均摊(包括添加表情消息的操作)O(logn)。更新热度要先从堆里删除原热度再添加新热度。
send_indirect_message
采用堆优化Dijkstra算法
每次查询时跑一遍最短路,复杂度O(E log E),E边数
优化,如果从优先队列里取出的点是终点,直接return

理论上强测可以卡掉最短路为O(E log E)复杂度的做法,但是助教们并没有卡,给助教点赞
上一篇:OO第四单元总结&课程总结


下一篇:OO第三单元——JML