Algorithm 使用后缀树的近似子字符串匹配

Algorithm 使用后缀树的近似子字符串匹配,algorithm,string-matching,suffix-tree,edit-distance,Algorithm,String Matching,Suffix Tree,Edit Distance,本文讨论了近似子串匹配技术,该技术利用a来提高匹配时间。每个答案都针对不同的算法 近似子字符串匹配尝试在字符串T中查找子字符串(模式)P,最多允许k不匹配 要了解如何创建后缀树,请单击。然而,有些算法需要额外的预处理 我邀请人们添加新的算法(即使是不完整的算法)并改进答案。这是本主题的原始问题 Esko Ukkonen教授发表了一篇论文:后缀树上的近似字符串匹配。他讨论了具有不同匹配时间的3种不同算法: 算法A:O(mq+n) 算法B:O(mq日志(q)+输出大小) 算法C:O(m^2q+输出大

本文讨论了近似子串匹配技术,该技术利用a来提高匹配时间。每个答案都针对不同的算法

  • 近似子字符串匹配尝试在字符串
    T
    中查找子字符串(模式)
    P
    ,最多允许
    k
    不匹配
  • 要了解如何创建后缀树,请单击。然而,有些算法需要额外的预处理

  • 我邀请人们添加新的算法(即使是不完整的算法)并改进答案。

    这是本主题的原始问题

    Esko Ukkonen教授发表了一篇论文:后缀树上的近似字符串匹配。他讨论了具有不同匹配时间的3种不同算法:

  • 算法A:
    O(mq+n)
  • 算法B:
    O(mq日志(q)+输出大小)
  • 算法C:
    O(m^2q+输出大小)
  • 其中,
    m
    是子字符串的长度,
    n
    是搜索字符串的长度,
    q
    是编辑距离

    我一直在试图理解算法B,但在遵循这些步骤时遇到了困难。有人有过这种算法的经验吗?如能提供示例或伪算法,将不胜感激

    特别是:

  • 就后缀树或输入字符串而言,
    输出的大小是指什么?最后的输出阶段列出了
    T
    中所有标记为输出的
    r
    状态下出现的
    键(r)
  • 查看算法C,定义了函数dp(第四页);我不明白索引
    I
    代表什么。它没有初始化,并且似乎没有递增
  • 以下是我的信念(我将被纠正):

  • 在第七页,我们将介绍后缀树的概念;状态实际上是后缀树中的节点:让
    root
    表示初始状态
  • g(a,c)=b
    其中
    a
    b
    是树中的节点,
    c
    是树中的字符或子字符串。所以这代表了一种转变;从
    a
    ,沿着
    c
    表示的边,我们移动到节点
    b
    。这被称为转到过渡。因此,对于下面的后缀树,
    g(根,'ccb')=红色节点
  • Key(a)=边序列
    ,其中
    a
    表示树中的节点。例如,
    键(红色节点)=“ccb”
    。因此
    g(根,键(红色节点))=红色节点
  • 键(节点的子集)={Key(节点)|节点∈ S} 
  • 有一个后缀函数用于节点
    a
    b
    f(a)=b
    :用于所有(或者可能存在)
    a
    root
    ,存在字符
    c
    、子字符串
    x
    、节点
    b
    ,使得
    g(root,cx)=a
    g(root,x)=b
    。我认为,对于上面的后缀树示例,这意味着
    f(粉色节点)=绿色节点
    其中
    c='a'
    x='bccb'
  • 有一个映射
    H
    ,它包含后缀树中的一个节点和一个值对。该值由
    loc(w)
    给出;我仍然不确定如何评估这个功能。此字典包含尚未消除的节点
  • extract min(H)
    是指从
    H
    中获取具有对
    (节点,loc(w))
    中最小值的条目

  • 该算法的关键似乎与如何评估
    loc(w)
    有关。我用组合答案构建了后缀树;然而,这些算法在后缀trie(未压缩后缀树)上工作。因此,像深度这样的概念需要以不同的方式进行维护和处理。在后缀trie中,深度表示后缀长度;在后缀树中,深度仅表示树中的节点深度。

    您做得很好。我对算法不太熟悉,但今天读了报纸。你所写的一切都是正确的。你是对的,解释的某些部分假设了很多

    您的问题

    1.根据后缀树或输入字符串,输出的大小是指什么?最后一个输出阶段列出T中所有键(r)的出现情况,以及标记为输出的所有状态r

    输出由p在T中的最大k距离匹配组成。特别是,您将获得每个匹配的最终索引和长度。很明显,这也是O(n)(记住大O是一个上界),但可能更小。这是对不可能在少于O(p)的时间内生成p个匹配的事实的认可。其余的时间限制只涉及模式长度和可行前缀的数量,两者都可以任意小,因此输出大小可以占主导地位。考虑k=0,输入是“a”重复n次与模式“a”。 2.查看算法C,定义函数dp(第四页);我不明白我代表的是什么索引。它没有初始化,并且似乎没有递增

    你说得对。这是个错误。循环索引应该是
    i
    。那么
    j
    呢?这是与动态程序中正在处理的输入字符相对应的列的索引。它实际上应该是一个输入参数

    让我们后退一步。第6页的示例表格使用前面给出的方程式(1-4)从左到右逐列计算。这表明只需要前面的D和L列就可以得到下一列。函数
    dp
    只是从
    j-1
    计算列
    j
    的思想的一个实现。D和L的
    j
    列分别称为
    D
    L
    。列
    j-1
    D和L是
    D'
    Let r = root of (uncompressed) suffix trie
    Set r's cached d,l with formulas at end page 7 (0'th dp table columns)
    // Invariant: r contains cached d,l
    for each character t_j from input text T in sequence
      Let s = g(r, t_j)  // make the go-to transition from r on t_j
      if visited(s)
        r = s
        while no cached d,l on node r
          r = f(r) // traverse suffix edge
        end while
      else
        Use cached d',l' on r to find new columns (d,l) = dp(d',l')
        Compute |Q_j| = l[h], h = argmax(i).d[i]<=k as in the paper 
        r = s
        while depth(r) != |Q_j|
          mark r visited
          r = f(r)  // traverse suffix edge
        end while
        mark r visited
        set cached d,l on node r
      end if
    end for
    
    H = { (0 => root) }  // we use (loc => state) for min heap elements
    until H is empty
      (j => s_j) = H.delete_min  // remove the min loc mapping from 
      (d, l) = dp(d', l', j) where (d',l') are cached at paraent(s_j)
      Compute |Q_j| = l[h], h = argmax(i).d[i]<=k as in the paper
      r = s_j
      while depth(r) > |Q_j|
        mark r eliminated
        H.delete (_ => r)  // loc value doesn't matter
      end while
      set cached d,l on node r
    
      // Add all the "next states" reachable from r by go-tos
      for all s = g(r, a) for some character a
        unless s.eliminated?
          H.insert (loc(s) => s)  // here is where we use the trie to find loc
    
          // Update H elements that might be newly covered
          w = f(s) // suffix transition
          while w != null
            unless w.eliminated?
              H.increase_key(loc(w) => w) // using explanation in Lemma 9.
              w = f(w) // suffix transition
            end unless
          end while
        end unless
      end for
    end until