2021-面向对象设计与构造-第三单元总结
第九次作业
架构与设计策略
架构上,完全照搬给出的接口,对于每一个接口 (或异常抽象类) A
创建了 MyA
将其实现 (或继承)。
三次作业都是这么做的,因此不在后两次作业中进行赘述了。
绝大部分方法只需复制规格,异常类的实现使用 static
成员变量记录每个 id
的出现次数即可。
三次作业异常类大致相同,因此不在后两次作业中进行赘述了。
无向图中添加点、添加边、查询任意两点间是否连通、查询连通块数量,可以使用路径压缩+启发式合并的并查集,单次操作 \(O(\alpha(n))\) 或 \(O(1)\) 的复杂度内完成。
因为 id
是 int
范围内且强制在线,需要使用 HashMap
存储,时间上还要乘以一个小常数,不过问题不大。
查询 name
的排名直接复制规格进行暴力,单次复杂度不超过 \(O(|s|n)\),其中 \(|s|\) 是串长。写平衡树可以优化到 \(O(|s| \log n)\),但这么小数据范围根本没必要。
测试与 bug 分析
因为功能过于简单,主要采用随机生成数据和室友对拍的方法。同时构造了一些极端数据防止算法写假。
强测与互测中没有出现 bug,互测中主要采取看代码+构造的方法 hack 了 \(3\) 个人,hack 内容见下面的性能分析。
容器选择
MyNetwork
中使用 HashMap
存储每个 Person
,以及并查集中的 fa
数组与 siz
数组,键均为 id
。
MyPerson
中使用 HashMap
存储边的权值,键为 id
。
异常类中使用 HashMap
存储每个 id
的出现次数,键为 id
。
性能分析
我的实现中,复杂度瓶颈在于查询 name
的排名。
此外,查询连通块数量的 JML
规格是以 \(O(n^2)\) 次调用 isCircle
方法给出的,如果直接照搬规格, isCircle
的实现又比较慢,就可以被卡成 TLE,互测中也是根据这个问题进行 hack。
第十次作业
架构与设计策略
架构上,完全照搬给出的接口,对于每一个接口 (或异常抽象类) A
创建了 MyA
将其实现 (或继承)。
对于 Group
的 valueSum
,每次新增 Person
或删除 Person
时维护改变量,单次修改复杂度 \(O(n)\),单次查询复杂度 \(O(1)\)。
对于 Group
的 ageMean
和 ageVar
,通过维护 age
的和与平方和可以做到单次 \(O(1)\) 询问与修改,但是这并不是复杂度瓶颈,索性直接 \(O(n)\) 暴力。
剩下的方法就没有什么优化余地了,直接照搬规格即可。
需要注意的是以下两个坑:
valueSum
是有序的,每条边的权值要算两次。- 一个人可能在好几个组里,
addRelation
时要考虑将对应边的权值加到对应的Group
中。
测试与 bug 分析
因为功能过于简单,主要采用随机生成数据和室友对拍的方法。同时构造了一些极端数据防止算法写假。
强测与互测中没有出现 bug,互测中主要采取看代码+构造的方法 hack 了 \(2\) 个人,hack 内容见下面的性能分析。
组内另有一人使用了 ArrayList
而非 HashMap
,看代码时完全忽略,没有针对其进行构造,错失了这个机会。
容器选择
MyNetwork
中使用 HashMap
存储每个 Group
与 Message
,键值为对应 id
。
MyPerson
中使用 ArrayList
存储他收到的信息。
MyGroup
中使用 HashMap
存储其中的 Person
,键值为 id
。
性能分析
Group
中查询 valueSum
的 JML
规格是以 \(O(n^2)\) 次调用 isLinked
方法给出的,如果直接照搬规格,可以被卡成 \(O(n^3)\) 从而造成 TLE,互测中也是根据这个问题进行 hack。
第十一次作业
架构与设计策略
架构上,完全照搬给出的接口,对于每一个接口 (或异常抽象类) A
创建了 MyA
将其实现 (或继承)。
除了最短路,其它部分的规格都是单纯模拟,没有优化余地。
对于无负边权的单源最短路,使用优先队列实现的堆优化 Dijkstra 算法可以在 \(O(m \log m)\) 的复杂度内完成。
测试与 bug 分析
因为功能过于简单,主要采用随机生成数据和室友对拍的方法。同时构造了一些极端数据防止算法写假。
强测与互测中没有出现 bug,互测中主要采取看代码+构造的方法进行 hack,但大家写的都很对,因此没有 hack 成功。
容器选择
MyNetwork
中使用 HashMap
实现规格中的 emojiHeatList
。
MyNetwork
中利用 PriorityQueue
实现了堆优化 Dijkstra 算法。
性能分析
在本题的数据范围和 \(6\) 秒时限下,单次最短路询问 \(O(m \log m)\) 是可以通过的。
不过,需要注意 Dijkstra 的暴力算法并非毫无用途,其复杂度为 \(O(n^2)\),在稠密图上快于堆优化,例如这个题 CF1528D。
总结与收获
-
感谢课程组为我们减负,三次作业简直是从头暴力到尾,老爽了。
当然,一个缺点就是写博客不知道写啥,理论课上老师说要我们多写点儿,但是我觉得真的没啥好写的,如果助教审阅时觉得字数太少我可以再水一些(逃。 -
Java8 的
HashMap
非常人性化,当一个哈希值的元素过多时会将链表转化为红黑树,元素过少时又会将红黑树转化为链表,降低了哈希冲突的代价,也让我断绝了我卡哈希的想法。 -
理论课上老师多次提出:「形式化方法工程应用受限。」
这三次作业让我深刻体会到了这一点。一些方法寥寥几行就能写完,形式化规格却要写的特别臃肿冗长。如果说这么做的代价是能进行形式化验证,那么意味着可以做到严格意义上的无 bug,简直再好不过了。但是现实是还需要自己造数据进行测试,那「形式化」就会成为效率的阻碍。
希望以后能看到形式化验证在工程上广泛应用的那一天,
这样就再也不用担心没找出来的 bug 了。
原文地址:https://www.cnblogs.com/JJLeo/p/14828972.html
- Hello Bonjour!
- SQL Server 2008 FILESTREAM特性管理文件
- 验证码类库CaptchaMvc
- SQL Server : Browser服务
- 仿今日头条顶部导航效果
- iOS微信小视频优化心得
- ADO.NET Entity Framework CodeFirst 如何输出日志(EF 5.0)
- 仿火车出票效果
- ASP.NET SignalR HubPipelineModule
- 微信ANDROID客户端-会话速度提升70%的背后
- Vue.js前后端同构方案之准备篇—代码优化
- 仿今日头条滑动评论效果
- Android新一代多渠道打包神器
- 应用IBatisNet+Castle进行项目的开发
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法