【问题标题】:Ukkonen suffix tree: procedure 'canonize' unclearUkkonen 后缀树:程序“规范化”不清楚
【发布时间】:2012-04-10 22:23:30
【问题描述】:

'canonize' 函数(下面给出,来自 Ukkonen 的论文)是如何工作的,尤其是 while 循环何时结束?我认为 p' - k' 的值将始终小于 p - k 的值。我是对还是错?

procedure canonize(s, (k, p)):
1. if p < k then return (s, k)
2. else
3. find the tk–transition g'(s, (k', p')) = s' from s;
4. while p' − k' <= p − k do
5.     k  = k + p' − k' + 1;
6.     s  = s';
7.     if k <= p then find the tk–transition g'(s, (k', p')) = s' from s;
8. return (s, k).

【问题讨论】:

  • 我认为在论文中添加确切的引用会很好。这是 1995 年出现在 Algorithmica 中的论文吗?在这种情况下,参考将是 DOI 10.1007/BF01206331。
  • 论文可以定位到@​​987654321@

标签: string algorithm suffix-tree


【解决方案1】:

canonize 函数所做的是在this SA post 的最后描述的,我们考虑这样的情况:

情况是这样的:

  1. 活动点在(red,'d',3),即从红色节点出来的defg边的三个字符。

  2. 现在我们跟随一个后缀链接到绿色节点。理论上,我们的活动节点现在是(green,'d',3)

  3. 不幸的是,该点不存在,因为从绿色节点出来的de 边只有两个字符。 因此,我们应用canonize 函数

它的工作原理是这样的:

  1. 我们感兴趣的边的起始字符是d。这个字符在 Ukkonen 的符号中称为 tk。所以,“找到tk-edge”就是在绿色节点找到de边。

  2. 这条边只有两个字符的长度。 IE。 (p' - k') == 2 在 Ukkonen 的符号中。但原来的边缘有三个字符:(p - k) == 3。所以&lt;= 为真,我们进入循环。

  3. 我们将寻找的边缘从def 缩短到f。这就是p := p + (k' - p') + 1 步骤的作用。

  4. 我们前进到de 边缘指向的状态,即蓝色状态。这就是s := s' 所做的。

  5. 1234563此步骤将 k' 和 p' 设置为全新的值,因为它们现在引用字符串 fg,其长度 (p' - k') 现在将为 2。
  6. 剩余边 f 的长度 (p - k) 现在为 1,新活动点的候选边 fg 的长度 (p' - k') 为 2。因此循环条件

    while (p' - k')

不再是真的,所以循环结束了,新的(和正确的)活动点确实是(blue,'f',1)

[实际上,在 Ukkonen 的表示法中,边的结束指针 p 指向边的最后一个字符的位置,而不是它后面的位置。因此,严格来说,(p - k) 是 0,而不是 1,(p' - k') 是 1,而不是 2。但重要的不是长度的绝对值,而是两个不同的相对比较长度。]

最后几点说明:

  • 像 p 和 k 这样的指针指的是原始输入文本 t 中的位置。这可能会让人很困惑。例如,绿色节点处de边使用的指针将引用t的some子字符串de,蓝色节点处fg边使用的指针将引用到 some 子字符串 fg 的 t。尽管字符串defg 必须作为一个连续字符串出现在t 中的某处,但子字符串fg 也可能出现在其他地方。所以,fg边的指针k不一定de边的结束指针p加一

  • 因此,当我们决定是否结束循环时,重要的不是绝对位置 k 或 p,而是剩余边的长度 (p - k) 与长度 (p' - k' 的比值) 的当前候选边。

  • 在您的问题中,代码 sn-p 的第 4 行有一个错字:应该是 k' 而不是 k;

【讨论】:

  • 感谢您的回答,它清除了规范化的各个方面。如果您可以为更新、测试和拆分以及特别是 Algorithm 2 的最后一行(在调用 update 后调用 canonize)提供解释,这对我和所有其他在理解后缀树方面有问题的人将非常有帮助。 ............再次为你和thanx欢呼......
  • 我同意,将这些各种函数的原始名称放在我上面提到的算法的综合 SA 帖子中确实是一个好主意。我很快就会这样做。但如果还有其他问题(很有可能),我们应该在单独的 SA 帖子中处理这些问题。
【解决方案2】:

我不得不更改 canonize 函数,因为它没有正确处理辅助状态。我在 'p

if (s == auxiliary)
{
    s = root;
    k++;
    if (p < k)
        return;
}

似乎现在可以工作了:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 2010-11-21
    • 2014-11-21
    • 1970-01-01
    • 2012-03-16
    • 2012-12-25
    相关资源
    最近更新 更多