具体实现
下面则是具体的代码实现,其实算法不像是实现一个业务功能这样好用文字分析;具体还是看源码多调试就明白了。
谈下几个重点的地方吧:
字典树的节点实现,其中的 isEnd
相当于图中的上色。
利用一个 Node[] children
来存放子节点。
为了可以区分大小写查询,所以子节点的长度相当于是 26*2
。
写入数据
这里以一个单测为例,写入了三个字符串,那最终形成的数据结构如下:
图中有与上图有几点不同:
- 每个节点都是一个字符,这样树的高度最高为52。
- 每个节点的子节点都是长度为 52 的数组;所以可以利用数组的下标表示他代表的字符值。比如 0 就是大 A,26 则是小 a,以此类推。
- 有点类似于之前提到的布隆过滤器,可以节省内存。
debug
时也能看出符合上图的数据结构:
所以真正的写入步骤如下:
- 把字符串拆分为 char 数组,并判断大小写计算它所存放在数组中的位置
index
。
- 将当前节点的子节点数组的 index 处新增一个节点。
- 如果是最后一个字符就将新增的节点置为最后一个节点,也就是上文的改变节点颜色。
- 最后将当前节点指向下一个节点方便继续写入。
查询总的来说要麻烦一些,其实就是对树进行深度遍历;最终的思想看图就能明白。
所以在 cim 中进行模糊匹配时就用到了这个结构。
字典树的源码在此处:
其实利用这个结构还能实现判断某个前缀的单词是否在某堆数据里、某个前缀的单词出现的次数等。
总结
再没有新的 BUG
产生前会着重把这些功能完成了,不出意外下周更新 cim
的心跳重连等机制。
完整源码: