OO第三单元总结

OO第三单元总结

1.设计策略

第九次作业

​ 难点在 isCircle 和 queryBlockSum 上,即判断两点是否联通以及查询连通块分量,最好的方法是采用并查集去维护,附上简单的一行并查集代码。

int find(x) { return fa[x] == x ? x : fa[x] = find(fa[x]);
void merge(int x,int y) {if(find(x) != find(y)) fa[find(x)] = find(y);}

​ 查连通块个数看有多少个 fa[i] = i 即可

第十次作业

​ 用普通方法查询年龄和方差时间开销过大,这里可以采用修改时维护年龄和以及年龄平方的和,用 \(E(x) = sum/2 \quad D(x) = E(x^2) - E^2(x)\) 来快速计算平均数和方差,需要注意的是由于题目要求是整数,如果我们计算时也使用整数,就可能出现误差,需要细节处理一下。

​ getValueSum函数,如果在network中完成需要用 \(O(people^2)\) 的复杂度,我选择了在group中实现,这样二重循环计算减少了 people 的数量,略微减少了复杂度。还有一种方法是维护group中的边权和,查询虽快,addToGroup 和 delFromGroup 维护复杂度也可以忍受,但是 addRelation 函数需要在所有的组里面都修改两人之间的连边,这个复杂度就高了。这两种方法理论上构造最差的数据都是会超时的,这里选择了第一中写法。

第11次作业

难点是sendIndirectMessage,采用 Dijkstra 算法可以实现 \(O(VlongV)\)的单点最短路,使用容器prorityQueue 就不用手写堆了。

2.测试方法和策略

这次我很懒,过了中测之后就没进行测试了,这也付出了惨痛的代价,第十次作业和第十一次作业都强侧只有十分,虽然当时没有测试方法和策略,我在这里补上。

我会先采取一般性测试,及尽可能的覆盖到所有的测试指令和数据范围,并且保证所有异常都要产生(第十次左右就是因为异常抛出单词拼错)。指令尽量平均,保证所有指令都出现。

之后对易错或者时间开销大的指令进行专门测试,比如第九次的 queryBlockSum 是复杂度最高的,我们可以让指令大多为 添加熟人和查询连通块,看是否超时或者出错。第11次针对group的三次查询和 emojimessage的指令集中测试,这样保证遇到极端数据数据代码也不会超时。

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

本单元我主要是用了 Arraylist 和 Hashmap。在人与人的massage发送的模块我选择了使用Arraylist,因为要查询前三条,直接 add(message,0) 即可加入链表头部。network 里面我大多也都使用了Arraylist,虽然Hashmap 复杂度更低,但一点失误就会出现空指针的问题。跑最短路是,因为 id 大小不定,我使用 Hashmap 把人的 id 映射到 1~n ,方便跑最短路。

4. 分析性能问题

第九次作业中,一开始我感觉用dfs实现图的遍历也可以通过测试 ,个人计算,即使全是queryBlockSum ,复杂度为 \(O(n^3)\) n大概在三百左右,按照之前写 C 语言的题目的经验,2s 按理来说应该是足够了。然而我高估了java 的运行速度,毕竟是比赛里给与双倍运行时间的语言,我还是在互测中超时了。以后这类问题最好还是自己构造数据实际测试一下,这样正确的估计自己的运行时间。

5. 作业架构设计

本次作业是一个通讯系统,可以实现单人和群体发送多种信息,同时支持人人之间加好友,建群等操作。是一个非常经典的通讯网结构,可以用向量的图去维护,加边,删边,判连通性和跑最短路都比较方便。维护也很方便,加边直接add,删边直接remove,复杂度高了点,但通过测试还是可以的。同时群的查询采用了维护变量的方法,这样减小了查询时的复杂度。

posted @ 2021-05-30 17:16  waing  阅读(65)  评论(1编辑  收藏  举报