BUAA OO unit_3

BUAAOO_UNIT3

1.总结分析自己实现规格所采取的设计策略

1.规格模式

这一单元训练的是我们对JML的掌握,一个是对规格逻辑的抽取、一个是自己会写逻辑完整的JML。

面向JML,采取规格模式编写代码,对规格的需求进行分析提取,寻找共性、必须数据、辅助数据、整体架构、所需要的数据结构等进行大致的分析后,按照每一个类、每一个方法的JML中的规约逻辑进行代码实现。

在具体实现JML时,大致了解的了类规格所定义的类的作用后,先考虑数据规格,在这作业总提到的数据,我优先选取了使运行时间较短的数据结构来实现,比如HashMap,在最短路径中选取优先队列对路径长度进行记录。此外,实现方法的时候,我会先完成exception的情况,再处理正常情况。如果实现简单的可以就按照JML的原话进行“翻译”即可。如果实现需要基于其他未规定的方法来实现,则需要注意在此后规格扩展的时候是否需要调整自己额外设计的方法。

2.结合课程内容,整理基于JML规格来设计测试的方法和策略

1.根据 JML的规定进行各种范围的对拍

检测正确性:通过大范围测exception,小范围测其他指令的实际实行正确性,可以通过控制id号的范围,控制测试的重点。此外对范围周围的数据进行测试如1111,为了防止和同学出现同样的对JML的错误理解或者出现同样的实现错误,要和很多同学对拍。

检测性能:第二次作业可以通过制造qbs,qgvs,qgav,qgam进行性能测试,第三次作业通过制造sim进行性能测试。

2.将JML的逻辑对应上自己的代码

对着JML的规格、逻辑、约束对应自己的代码一项一项对应检查。但更加合理的方法是通过Junit进行正确性的检验,尤其针对边缘数据。

3.总结分析容器选择和使用的经验

在这次作业中,对于JML规定的成对出现的且如果下标相同就表示一一对应的数组我均采用了HashMap类型,利用题目规定的独一无二的id作为key值。由于在最短路径中采用迪杰斯特拉算法,每次更新最短路径的时候,需要查找到最短的一条,所以采取优先队列。

此外,其他的一些容器的选择的。例如实现了list接口的ArrayListlinkedListArrayList底层由数组支持,而后者是由双向链表实现的,因此如果表中插入或删除元素,后者更加合适,否则前者会更快。实现了set接口的几种容器中,HashSet查询速度最快,尤其是在没有HashMap这种成对出现的元素且集合中元素互异时。LinkedHashSet可保持插入次序,TreeSet基于TreeMap,生成总是处于排序状态的set。TreeMap是通过能够保持搜索效率平衡的红黑树,是一种有序的Map。PriorityQueue,堆的数据结构来保持排序的状态。

4.针对本单元容易出现的性能问题,总结分析原因如果自己作业没有出现,分析自己的设计为何可以避免

1.第一次作业

这一次作业最容易出现的错误是qbs,计算连通块的个数,如果通过递归深搜,时间开销很高容易导致性能Bug,因此采取并查集,并且在每次查找的时候,将节点压缩到最根部的节点,所以可以提高效率。而在每次进行连通块合并的时候,将前一个块的根部节点的根节点直接连在后一个上面。在询问块的数量的时候仅需对Person进行遍历,如果根和自己的id相同则计算一个块,O(n)的复杂度即可。

 

 

另外一种有意思的计算方法是通过两层ArrayList进行计数,每个小的ArrayList记录一个块内的所有数据点,而大的一层的记录块。这样一来,在添加关系的时候会导致查询上有O(n)的复杂度,但是在计算块总数的时候只有O(1).

 

 

2.第二次作业

这次作业中qgam,qgav是容易出现性能bug,如果每次询问就对group进行遍历加总数,就容易导致时间超出,通过计数总数以及平方数总数,可以将这个封装为一个类,将所有的计数(包括exception)都封装起来,然后通过调用计数类将平方和、总和汇总,可以用static类记录调用次数。此外还需要注意的地方在于JML规格对于方差的解释是通过去掉小数点的平均数求得,不能直接通过平方平均减去平均数的平方,而应该采用化简的上一级公式如下所示。

 

 

 

 

3.第三次作业

寻求最短路径使用Dijkstra算法加上堆优化的方法,让复杂度变为Elog(E),当边较少时不会退化为V^2log(V^2),题目限制输入已经保证了该点。但是性能出现Bug,不知道原因,但是在一些针对sim函数做大量测试的时候,在有的数据上会明显慢于对拍的同学出现超时,我采用了优先队列对已经可以连接到的点的距离进行了维护,但是仍然在一个点上TLE。

deleteColdEmoji的目的是消去热度低的表情包,同时限制了message不得使用不存在的表情包。而理解完这个规格后,就无需再用一个两层嵌套遍历了,仅需两次对message和emojiId遍历删除即可。

5.梳理自己的作业架构设计,特别是图模型构建与维护策略

 

 

这个是针对第三次作业中出现的多种message进行了继承。

关系图谱的维护通过每个Person类中加入HashMap对认识的人进行关联,再通过在network中添加HashMap维护每一个人所属关联圈的根节点的人。

在求最短路径中添加了节点的类,用于记录到每个节点的距离。添加异常计数类,利用多态使得代码更加简便漂亮。添加了方差计数类。此外就是按照接口来进行类的设计。

方法上,也大多按照规格来写,除了必要的需要我们自己去衔接的地方,比如ar指令中需要我们自己去实现Person的熟人的添加。

 

总的来说这一单元的作业不算很难,只是需要自己对大量的JML进行理解推测总结,然后在这个过程中容易遗漏混淆,多加注意即可。然后就是艰难的迷惑的tle,希望下周能找到原因(TAT)。

 

 

 

posted @ 2021-05-30 21:10  YSMY  阅读(76)  评论(1编辑  收藏  举报