4 最容易想到的:即从字符串集中从头往后搜,看每个字符串是否为字符串
集中某个字符串的前缀,复杂度为 6!。
!4 使用 5#5:我们用 5#5 存下所有字符串的所有的前缀子串,建立存有
子串 5#5 的复杂度为 ,而查询的复杂度为 9
。
34 使用 :因为当查询如字符串 是否为某个字符串的前缀时,显然以
''4444等不是以 开头的字符串就不用查找了。所以建立 的复杂度
为 ,而建立+查询在 trie 中是可以同时执行的,建立的过程也
就可以成为查询的过程,5#5 就不能实现这个功能。所以总的复杂度为
,实际查询的复杂度也只是 。(说白了,就是 树的
平均高度 5 为 ,所以 树的查询复杂度为 (5)9()。好
比一棵二叉平衡树的高度为 :,则其查询,插入的平均时间复杂度亦
为 (:))。
下面解释下上述方法 3 中所说的为什么 5#5 不能将建立与查询同时执行,而
树却可以:
在 5#5 中,例如现在要输入两个串 ;,;<=7,如果要同时查询这两个串,
且查询串的同时若 5#5 中没有则存入。那么,这个查询与建立的过程就是先查
询其中一个串 ;,没有,然后存入 ;、;、;;而后查询第二个串
;<=7,没有然后存入 9、91、911、;<、;<=、;<=7。因为程序
没有记忆功能,所以并不知道 ; 在输入数据中出现过,只是照常以例行事,
存入 ;、;、;、;<、;444。也就是说用 5#5 必须先存入所有子串,
然后 循环查询。
而 树中,存入 ; 后,已经记录 ; 为出现的字符串,在存入 ;<=7 的过
程中就能发现而输出答案;倒过来亦可以,先存入 ;<=7,在存入 ; 时,
当指针指向最后一个 时,程序会发现这个 已经存在,说明 ; 必定是某个
字符串的前缀。
读者反馈>悠悠长风:关 于这点,我有不同的看法。hash 也是可以实现边建立边
查询的啊。当插入 911 时,需要一个额外的标志位,表示它是一个完整的单词。
在处理 911456 时,也是按照前面的查询 9,91,911,当查询 911 时,是可以找到
前面插入的 911,且通过标志位知道 911 为一个完整单词。那么就可以判断出
911 为 911456 的前缀啊。虽然 trie 树更适合这个问题,但是我认为 hash 也是可
以实现边建立,边查找。
吾答曰:但若反过来呢?比如说是先查询 911456,而后查询 911 呢?你的在 hash
中做一个完整单词的标志就行不通了。因为,你查询 911456 时,并不知道后来
911 会是一个完整的单词。
至于,有关 树的查找,插入等操作的实现代码,网上遍地开花且千篇一律,
诸君尽可参考,想必不用我再做多余费神。
评论2
最新资源