我们什么时候实际使用Trie?

时间:2012-05-22 07:32:08

标签: regex algorithm optimization data-structures trie

我开始读到Trie。我也收到了朋友的推荐信:Tutorials on Trie

我不清楚以下内容:
似乎继续使用Trie,假设所有将成为搜索空间并用于构建Trie的输入字符串在不同的字边界中分开。
例如。我见过的所有示例教程都使用输入,例如:

S={ball, bid, byte, car, cat, mac, map etc...}

然后我们从S构建trie并进行搜索(非常快) 我的问题是:我们最初是以S开头的? 我的意思是在开始阅读尝试之前我想象S将是一个任意长的文本,例如一段Shakespeare段。

然后使用Trie我们可以很快找到东西 但似乎事实并非如此。

此处假设输入段落(例如Shakespeare)是预先处理的,首先提取所有单词以获得S

因此,如果想要搜索模式(与Google相同,并且在搜索查询中看到所有页面也有空格),则Trie不合适?
我们何时才能知道Trie是否是我们实际可以使用的数据结构?

4 个答案:

答案 0 :(得分:6)

如果您想要快速查找固定字典,则尝试非常有用。与散列表相比,它可能需要较少的存储空间来存储大型字典,但查找起来可能需要更长时间。我使用它的一个示例位置是将URL映射到Web服务器上的操作,因为可能存在基于前缀的功能继承。在这里递归trie可以适当查找需要为特定url调用的所有方法。存储字典也很有效。

对于进行文本搜索,您通常会使用具有权重的leximes的令牌向量(可能基于出现频率)来表示文档,然后搜索该文档以针对特定搜索向量获取文档的排名。有许多标准库可以做到这一点我建议使用而不是编写自己的 - 特别是删除停用词,处理同义词和词干。

答案 1 :(得分:2)

我们可以在线性时间内使用try进行子字符串搜索,而不必每次都预先处理字符串。您可以获得关于后缀树生成的最佳教程@     Ukkonen's suffix tree algorithm in plain English?

答案 2 :(得分:2)

正如其他例子所说,trie非常有用,因为它提供了快速的字符串查找(或者更常见的是,任何序列的查找)。我尝试过的地方的一些例子:

  • My answer to this question使用(略微修改过的)trie来匹配句子:它是基于一系列单词而不是一系列字符的trie。 (该问题的其他答案可能更清楚地表明了行动中的特里。)
  • 我还在一个游戏中使用了一个特里游戏,其中有大量的房间有名字(总数和名字是在运行时定义的),每个名字都必须是唯一的,一个必须能够快速搜索具有给定名称的房间。也可以使用哈希表,但在某些方面,trie更易于实现,并且在使用字符串时更快。 (我的trie实现结果是~50行C。)

标记可能包含更多示例。

答案 3 :(得分:2)

使用尝试有多种方法。典型的例子是查找,例如您提供的查找。但是,Tries也可用于完整索引完整的文本。您可以使用Ukkonen后缀树算法来生成后缀trie,也可以通过存储后缀来明确地构造后缀trie(比Ukkonens算法慢得多,但也简单得多)。因为这是预处理,只有在速度不是那么重要时才需要进行预处理。

为此你只需要你的文字,插入全文,然后砍掉第一个字母,插入结果文字,插入第二个字母,插入......

因此,如果我们有“文本”文本,我们将插入以下集合:

{"The Text", "he Text", "e Text", " Text", "Text", "ext", "xt", "t"}

在生成的后缀trie中,我们可以轻松搜索任何类型的前缀。这也是节省空间的,因为我们不需要存储整个字符串,因为公共前缀只存储一次。

如果您需要有效地存储更长的字符串空间,最好不仅要将前缀存储在一起,还要将后缀存储在一起。在这种情况下,你可以建立一个有向无环字图(DAWG),这与概念中的特里非常相似。

因此,在这种意义上的特里允许找到任意子串,包括部分词。如果您只对存储单词感兴趣,则应使用不同的数据结构,例如倒排列表(如果顺序很重要)或基于向量空间的检索算法(如果单词顺序无关紧要)。