OO第三单元总结

OO第三单元总结

设计策略

本单元主要是根据课程组所给的JML来实现一个简单的社交关系模拟系统。所以在每次作业,我先根据JML直接最简单的实现一遍,然后针对复杂度较高的函数进行优化。

关于容器

由于person、group、message都有其专有的id,所以自然而然地想到利用HashMap,以id为key,相应object为value将它们进行存储。特殊地,对于Person类,由于acquaintance存储的是与其直接相连的Person(结点),所以以Person为key,他们间的value为value(即他们间的距离)进行存储,方便查询;还有Network类中的emojiHeatList,将emojiHeatList和emojiIdList合并在一起,以id为key,emojiheat为value进行存储。对了,还有每个异常类里头的计时器Counter中计算每个id发生一场次数也是用的HashMap。

对于每个Person收到的messages,需要满足在头部插入新元素和查询前4个元素的需求,所以利用LinkedList进行维护,插入查询均为\(O(1)\)

在优化dij的时候用到了PriorityQueue,十分方便的实现了最小值的查询。

关于性能

对于本单元的测试对于性能是有一定要求的,复杂度超过\(O(n^{2})\)基本都会CTLE,所以对于作业中一些算法不能死板地照抄JML,需要一定的优化,并且对于一些查询进行操作离散化。

第九次作业

本次作业主要在于isCircle和qbs两个函数,我采用的是并查集,利用DisjointSet类,维护一个其中blockSum常量及find数组,在每次ap和ar的时候进行更新,\(O(n)\)更新,\(O(1)\)查询。

第十次作业

本次作业引入Group类,并添加了对其一些属性的求取的函数,即qgvs、qgav。

对于qgvs,若直接按照JML会导致复杂度达到\(O(n^{2})\)超时,所以我选择维护一个变量valueSum表示边权和,在每次向group添人或减人时进行\(O(n)\)更新,\(O(1)\)查询。同时要注意,在ar的时候也要对作为操作对象的两人所在group进行更新。

对于qgav、qgam,维护ageSum、ageSquare变量维护年龄之和及年龄的平方和,根据公式可以得到方差和平均值,\(O(1)\)更新\(O(1\))查询。

对于qnr,由于题目限制了名字长度不超过10并且qnr出现次数不超过333,所以直接暴力遍历复杂度\(O(|s|*n)\)问题也不大。

第十一次作业

本次作业引入了几种不同的Message,并加入了函数sendIndirectMessage,需要求两点最短距离,采用堆优化的dij算法,复杂度\(O(mlogn)\)

测试方法

对于每次作业,先随机生成指令进行正确性验证,再针对性能可能出现问题的函数进行针对性构造,与几位同学继续对拍测试。

互测阶段,也是先利用随机指令进行正确性测试,然后通过看同房同学的代码的几个关键函数,看复杂度是否会导致CTLE,再针对性构造数据。

第九次作业

一开始用dfs实现isCircle,按照JML直接用isCircle实现qbs,复杂度高达\(O(n^{3})\),导致CTLE,后改用并查集即可。

互测阶段,发现一位同学同样如此,构造极端数据将其hack。

第十次作业

互测阶段主要针对qgvs进行极端数据构造,前2000条指令用于ap及atg,后面全是qgvs,成功hack到同房几位同学,但也由于这样的数据构造方式,让我忽略了atg后对于group中两人进行ar同样需要更新valueSum。

第十一次作业

本次互测同房均采用堆优化的dij,并对valueSum进行了离散化更新,未能hack。

图模型构建与维护策略

本单元作业所涉及的社交网络关系图模型主要特点在于其会动态增删点、动态增加带权边、无重边(没有涉及删除边)。我们需要达到的要求为:查询两点的连通性、查询特定点集的边权和、查询连通块个数、查询两点最短路。

其实课程组给的几个类已然为我们设计好了整个图的构造,Network为整个图,Person为图中的点,Group为若干点构成的点集。由于不涉及删除边,所以达成要求的难度较为简单,只需要利用并查集维护联通性,dij求最短路,实时更新各点集边权和即可解决。

心得体会

JML确实能够解决文字表述上可能存在的一些歧义性问题,但是由于需要考虑十分周全,有时候规格太长太长了,比实现的代码还长,略显臃肿,编写者应该也挺难受的(从若干次更新JML可以看出),可能这也是为啥现在没广泛使用与实际工程的原因之一。

posted @ 2021-05-31 17:59  Sharpzz  阅读(68)  评论(0编辑  收藏  举报