后缀树和尝试。有啥区别?
Posted
技术标签:
【中文标题】后缀树和尝试。有啥区别?【英文标题】:Suffix tree and Tries. What is the difference?后缀树和尝试。有什么区别? 【发布时间】:2012-12-03 08:32:33 【问题描述】:我正在阅读关于 Tries
通常称为前缀树和 Suffix Trees
的信息。
虽然我找到了Trie
的代码,但我找不到Suffix Tree
的示例。我也觉得构建Trie
的代码与Suffix Tree
的代码相同,唯一的区别是在前一种情况下我们存储前缀但在后缀中。
这是真的?任何人都可以帮我清除这个问题吗?一个示例代码会很有帮助!
【问题讨论】:
TL;DR 字符串的后缀树是其所有后缀的patricia trie。唯一的特殊之处在于边缘标签是原始字符串的子字符串,因此它们可以表示为一对索引并且只占用恒定空间。这也是它可以在线性时间内构建的原因。 【参考方案1】:后缀树可以看作是建立在 trie 之上的数据结构,其中不仅将字符串本身添加到 trie 中,还可以添加该字符串的每个可能的后缀。例如,如果您想在后缀树中为字符串 banana 建立索引,您可以使用以下字符串构建一个 trie:
banana
anana
nana
ana
na
a
完成后,您可以搜索任何 n-gram 并查看它是否存在于您的索引字符串中。换句话说,n-gram 搜索是对字符串所有可能后缀的前缀搜索。
这是构建后缀树的最简单和最慢的方法。事实证明,这种数据结构有许多更奇特的变体,它们可以改善空间和构建时间中的一个或两个。我对这个领域不够精通,无法给出概述,但您可以从查看 suffix arrays 或此类 advanced data structures 开始(第 16 和 18 讲)。
这个answer 也很好地解释了这个数据结构的一个变体。
【讨论】:
这就是我的怀疑。trie 是用来构建后缀树的,这也是为什么大多数教科书只提供 try 的代码。但这是最坏情况下的实现吧? @Cratylus 后缀树在非常大的字符串(例如,索引莎士比亚的所有作品)上最有用,其中 O(n^2) 的空间和构建时间根本不会减少它。幸运的是,这些界限可以降低很多。【参考方案2】:如果您想象一个 Trie,其中您放置了一些单词的后缀,您将能够非常轻松地查询它以查找字符串的子字符串。这是后缀树背后的主要思想,它基本上是一个“后缀树”。
但是使用这种幼稚的方法,为大小为 n 的字符串构建这棵树将是 O(n^2) 并且占用大量内存。
由于这棵树的所有条目都是同一字符串的后缀,它们共享大量信息,因此有优化的算法可以让您更有效地创建它们。例如,Ukkonen 的算法允许您以 O(n) 的时间复杂度在线创建后缀树。
【讨论】:
所以你是说后缀树和后缀尝试是一样的?【参考方案3】:区别很简单。后缀树的“虚拟”节点少于后缀树。这些虚拟节点是增加树上查找操作的单个字符
【讨论】:
【参考方案4】:Trie 的节点有链接到较短的上下文,'Tree' 没有它。如果 Tree 的节点链接到较短的上下文,那么它会转向 Trie ;o)
【讨论】:
【参考方案5】:给定文本的后缀树是给定文本的所有后缀的压缩树。
参考:https://www.geeksforgeeks.org/pattern-searching-using-suffix-tree/
【讨论】:
【参考方案6】:我会给你 sn-ps 让你的理解更清楚。 免责声明:我不是专家,我从编码面试准备中了解这些 DS。
首先,如上所述:suffix trie 是由哈希表(最简单的变体)组成的结构,我们在其中存储所有可能的变体。因此,如果需要,我们可以搜索子字符串。 例如:'abc'。
'a': True,
'a': 'b': True,
'a': 'b': 'c': True,
'b': True,
'b': 'c': True,
'c': True
Trie 是我们存储完整字符串以检查它们是否存在的时候。
例如:'t': 'h': 'i': 's': '*': 'this', 'y': 'o': '*': 'yo'
你可以在 Leetcode 上查看更多解释问题:Implement Trie (Prefix Tree)。链接:https://leetcode.com/problems/implement-trie-prefix-tree/
【讨论】:
以上是关于后缀树和尝试。有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章