第3届83行代码大赛第2关赛题官方解析

简介: 由阿里云云效主办的2021年第3届83行代码挑战赛已经收官。超2万人围观,近4000人参赛,85个团队组团来战。大赛采用游戏闯关玩儿法,融合元宇宙科幻和剧本杀元素,让一众开发者玩得不亦乐乎。

其中大赛第二题,号称魔鬼算法题,拦住诸多代码好汉。


我们请来了第二题的出题人,刘力华(阿里云云效代码平台),为大家系统揭秘,从设计到攻略,还有优秀代码解析供大家参考。



赛题设计


我设计的第二关是希望能考察参赛者的基础算法、数据结构的能力。

设计来源

本赛题采用的是字符串前缀匹配算法,参数者需要先通过OSS获取待匹配的数据集,然后参赛者需要从中找出与指定前缀字符串相匹配的字符串数据。为什么会选择该算法呢?源于近期我在使用我们自己的开发插件时,它能够当我在代码搜索的输入框中输入Java API关键词时,可以自动提供API名称的补全提示,受该功能模块启发,因此希望设计一个题目让参赛者实现一个Java API名称的前缀匹配算法。


此处打个广告:我们的插件是阿里云智能编码插件,现已上架JetBrains插件市场,可以在IntelliJ IDEA中通过搜索Alibaba Cloud AI Coding Assistant下载使用。插件包含了代码智能补全及代码示例搜索功能,让开发者更快速、行云流水的完成编码。


整个赛题的设计难点在于如何让本赛题具备一定的挑战性。但又保证一定的通关率。该赛题在外部题库有类似的算法题,属于中等难度,所以中等难度能提高一定的通过率。为了避免参赛者通过Java的String.startsWith及双循环就直接通过,所以增大了评测的数据量,但是为了控制赛题难度,评测的数据集分为几十万的小数据集以及几百万的大数据集,只要能较好的解决小数据集问题,就能通过该赛题。

评分系统

本赛题的打分系统基于函数计算设计,系统会随机选择一个小规模数据集和一个大规模数据集,并依次串行运行参赛者的代码,并针对这两个数据集对参赛者编写的代码从准确性、性能开销、内存消耗维度进行评估。



赛题攻略

OSS数据获取

本赛题的数据集存储在OSS中,所以需要参赛者通过OSS的SDK进行数据的获取,参赛者可以通过代码注释中的文档链接去学习OSS SDK如何使用,也可以通过近期发布的阿里云智能编码插件(Cosy)快速查看OSS SDK的示例代码。



如上图所示,如果参赛者想知道OSSObject的数据如何获取,可以在该API上右键点击“查看代码示例”,智能编码插件就能快速查找出实现OSS数据获取相关的代码示例,参赛者只需要选择性复制并修改部分代码即可。


此外,开发者也能通过代码智能补全功能,通过选择整行的代码补全结果,快速的编写出获取OSS数据的代码,如下图所示。



算法攻略

该赛题的解题方法是比较多样化的,参赛者采用的方法主要分为以下几种。


第一种:自己实现算法及数据结构


赛题攻略中提到了Trie Tree,一个较为基础的数据结构,一个较好的Trie Tree也能够通关本赛题。但是Trie Tree的性能开销及内存消耗也都是比较大的,可以考虑Trie Tree的诸多变种,比如Double Array Trie,用双数组去节省空间,比如Radix Tree及其诸多变种,通过减少树的深度去压缩Trie Tree的内存占用。为了对比各种Trie Tree实现的效果,这里引用《MergedTrie: Efficient textual indexing》论文的相关评测数据。



还有很多参赛者通过减少双层循环的次数、减少前缀匹配的性能开销等方法,也同样获得了较高的分数。


第二种,使用JDK内置的数据结构


JDK内置数据结构的性能也是比较高的,部分参赛者使用了TreeSet进行排序,然后通过用subSet方法就能直接获取匹配的前缀字符串数据,该方式比较简单快捷,且代码量较小。

参赛代码SHOW

参赛者对本赛题的解法诸多,由于篇幅限制,本文章只展示四位参赛者的代码片段。

参赛者代码片段一

该解法通过String.substring方法去截取字符串不同长度的前缀,并将截取的前缀直接从result的Map中进行查找,该方法无需像String.startsWith逐一进行字符的比较,所以效率会有较大提升,使用这种解法的参赛者比较多,还有部分参赛者会对截取的长度进行限制,比如事先统计前缀字符串的最短及最长的长度,只需遍历生成该长度范围内的前缀即可。



参赛者代码片段二


该解法会先排除超出前缀字符串最短及最长长度范围的数据,然后对数据集进行排序。随后遍历待匹配的前缀字符串列表,为每个前缀字符串通过二分查找计算数据集中,与其匹配位置的数组上界及下界,然后将该范围内的数据抽取出来即可。



参赛者代码片段三

该解法与排序方法类似,使用了JDK内置的TreeSet进行排序,然后通过TreeSet.subSet方法截取与前缀字符串匹配的数据。



部分参赛者为了提高挑战性,放弃使用TreeSet,自己实现了相关的排序及查找方法



参赛者代码片段四


这是排名第一的参赛者的代码,该参赛者对Trie树进行了优化,使用CharNode、ArrayNode减少部分存储消耗,其中ArrayNode中通过shift存储偏移量,数组的下标位置加上shift偏移量即为字符的ASCII码。


并且该参赛者在输出数据时没有将字符串存储到字符串数组中,而是定义了ByteBuf,在输出时直接以JSON字符串形式存储到字节数组中。





总结

尽管很多参赛者在这一关遇到了较多困难,尤其是在处理大规模数据集时。但正因为如此,我们也发现很多选手并不止步于通关,他们会努力尝试不同的解法、不断地优化算法,哪怕只是提升了0.01分,这一点对我们团队的触动也是很大的。赛事后我们也反思了一些做得不够好的地方,比如IDE评分栏缺少内存消耗、性能开销等具体数字的展示,导致部分参赛者不知道实际的内存消耗,后续我们会对这些细节点上进行优化,如果大家有好的想法及建议,欢迎反馈给我们!


看完攻略如果你还想体验赛题,依然可以前往https://code83.ide.aliyun.com,我们目前仍然开放给大家进行体验。


最后,欢迎大家试用智能编码插件https://developer.aliyun.com/tool/cosy,它作为一款AI开发插件,拥有强大的代码智能补全、代码示例搜索等功能,让开发行云流水般编码,事半功倍地完成开发工作。你可以在IntelliJ IDEA或JetBrains插件市场中搜索Alibaba Cloud AI Coding AssistantCosy,使用中如果有任何问题或建议都可以反馈到Github Issues中,我们会认真倾听你的声音。



大赛目前全部关卡开放体验,域名地址:https://code83.ide.aliyun.com/,欢迎你来。


相关文章
|
机器学习/深度学习 算法 C++
2019第十届蓝桥杯大赛青少年创意编程省赛C++组试题解析
2019第十届蓝桥杯大赛青少年创意编程省赛C++组试题解析
416 0
|
6月前
|
JSON Android开发 数据格式
Android框架-Google官方Gson解析,android开发实验报告总结
Android框架-Google官方Gson解析,android开发实验报告总结
|
存储 缓存 NoSQL
Redis持久化深入解析(RDB 、AOF)—官方原版
Redis持久化深入解析(RDB 、AOF)—官方原版
280 0
|
存储 缓存 编解码
Spring缓存架构详解-Spring官方原版-全面解析
Spring缓存架构详解-Spring官方原版-全面解析
209 0
|
弹性计算 Cloud Native 关系型数据库
【官方首发】—阿里云云计算&数据库ACP认证的解析与实战系列电子书来啦!
重磅推出【云计算、数据仓库、关系型数据库】ACP认证的解析与实战电子书!认证备考必备学习资料,免费下载!
【官方首发】—阿里云云计算&数据库ACP认证的解析与实战系列电子书来啦!
|
安全 前端开发 网络安全
2021年江苏省职业院校技能大赛中职 网络信息安全赛项试卷--web安全渗透测试解析
2021年江苏省职业院校技能大赛中职 网络信息安全赛项试卷--web安全渗透测试解析
234 0
2021年江苏省职业院校技能大赛中职 网络信息安全赛项试卷--web安全渗透测试解析
|
机器学习/深度学习 负载均衡 算法
互联网+大赛-龙蜥社区赛题解析(基于 Pluasched 优化内核调度器)|学习笔记
快速学习互联网+大赛-龙蜥社区赛题解析(基于 Pluasched 优化内核调度器)
互联网+大赛-龙蜥社区赛题解析(基于 Pluasched 优化内核调度器)|学习笔记
|
存储 Cloud Native NoSQL
互联网+大赛-阿里云数据库赛题解析|学习笔记
快速学习互联网+大赛-阿里云数据库赛题解析
互联网+大赛-阿里云数据库赛题解析|学习笔记
|
机器学习/深度学习 存储 弹性计算
互联网大赛+命题解析-大规模云计算系统中计算子系统故障预测|学习笔记
快速学习互联网大赛+命题解析-大规模云计算系统中计算子系统故障预测
|
存储 Cloud Native 固态存储
赛题解析 | 第四届全球数据库大赛赛道2:分布式NewSQL性能挑战
第四届全球数据库大赛—PolarDB性能挑战赛,瓜分40万奖金池,只等你来!各赛道TOP10都可获得现金奖励
1479 0
赛题解析 | 第四届全球数据库大赛赛道2:分布式NewSQL性能挑战
下一篇
无影云桌面