【问题标题】:really hard to understand suffix tree真的很难理解后缀树
【发布时间】:2012-03-22 13:53:26
【问题描述】:

我一直在寻找有关后缀树的教程很长一段时间。在SO中,我找到了2篇关于理解后缀树的帖子:12

但我不能说我了解如何构建一个,糟糕。在 Skiena 的《算法设计手册》一书中,他说:

由于线性时间后缀树构造算法不平凡, 我建议使用现有的实现。

嗯,后缀树的在线构造算法有那么难吗?任何人都可以让我理解它的正确方向吗?

不管怎样,切入正题,除了构造之外,关于后缀树还有一件事我不明白。因为后缀树中的边只是一对整数(对吗?)指定子字符串的开始和结束位置,那么如果我想在这个后缀树中搜索字符串x,我该怎么做呢?取消引用后缀树中的这些整数,然后将它们与x 进行一一比较?不可能是这样的。

【问题讨论】:

    标签: algorithm suffix-tree


    【解决方案1】:

    首先,构建后缀树的方法有很多。有 Weiner (1973) 的原始 O(n) 方法,McCreight (1976) 改进的方法,Ukkonen (1991/1992) 最著名的方法,以及许多进一步的改进,主要与实现和存储有关效率考虑。其中最著名的可能是 Giegerich 和 Kurtz 的 Efficient implementation of lazy suffix trees

    此外,由于 后缀数组 的直接构造在 2003 年的 O(n) 时间内成为可能(例如使用 Skew algorithm,但也有其他的),并且因为有充分研究的方法

    后缀数组通常比后缀树更受欢迎。因此,如果您打算为特定目的构建高度优化的实现,您可能需要研究研究后缀数组构造算法。

    但是,如果您对后缀树构造感兴趣,特别是 Ukkonen 算法,我建议您仔细查看您已经提到的 this SO post 中的描述,我们会努力改进那个描述在一起。这肯定远不是一个完美直观的解释。

    回答关于如何将输入字符串与边标签进行比较的问题:出于构建和查找过程中的效率原因,每个边标签的首字符通常是存储在节点中。但是其余的必须在主文本字符串中查找,就像你说的那样,这确实会导致问题,特别是当字符串太大以至于不能轻易保存在内存中时。那(再加上一个事实,就像任何直接实现树一样,后缀树是一个包含大量指针的数据结构,这会消耗大量内存并使其难以维护引用局部性和从内存缓存中受益)是后缀树比例如更难处理的主要原因之一倒排索引。

    【讨论】:

    • 谢谢,确实后缀数组是一种正确且简单的方法。 :-)
    【解决方案2】:

    如果您将后缀数组与 lcp 表子表 组合在一起,当然您应该这样做,那么您实际上会得到一个后缀树。这一点在论文中提出:Kim、Park 和 Kim 的 Linearized Suffix Trees。 lcp 表实现了一种相当尴尬的自下而上的遍历,而 child 表实现了任何一种简单的遍历。因此,在我看来,关于使用指针导致引用问题的局部性的后缀树的故事是过时的信息。因此,后缀树是“正确且简单的方法”,只要您使用底层后缀数组来实现树。

    Kim、Park 和 Kim 的论文描述了 Abouelhoda 等人的论文中的一种变体方法:用增强的后缀数组替换后缀树。 Kim 等人的论文认为这是后缀树的实现,而不是替代。此外,Abouelhoda 等人的构造细节在 Kim 等人的描述中更加简单直观。

    【讨论】:

      【解决方案3】:

      这里有一个 Ukkonen 的后缀树(加上后缀数组,lcp 数组)的线性构造的实现:http://code.google.com/p/text-indexing/。与 suffixtree.js 一起提供的可视化可能会有所帮助

      【讨论】:

      • 请注意 link-only answers 是不鼓励的,所以答案应该是寻找解决方案的终点(而不是另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,并保留链接作为参考。
      • 嘿.. 已经建议您不要发布仅链接的答案,为什么不学习?
      猜你喜欢
      • 2012-12-17
      • 1970-01-01
      • 2021-04-24
      • 2010-11-07
      • 1970-01-01
      • 2015-05-24
      • 2020-12-02
      • 1970-01-01
      相关资源
      最近更新 更多