【问题标题】:Looking for ideas: lexicographically sorted suffix array of many different strings compute efficiently an LCP array寻找想法:许多不同字符串的按字典顺序排序的后缀数组有效地计算 LCP 数组
【发布时间】:2012-12-26 06:52:50
【问题描述】:

我不想直接解决这个问题的根源,但这是link

所以我接收字符串并将它们添加到后缀数组中,该数组在内部实现为排序集,然后我获得的是两个给定字符串的字典排序列表。

S1 = "banana"
S2 = "panama"

SuffixArray.add S1, S2

为了高效搜索k-th 最小子字符串,我对这个排序集进行了预处理,以添加有关后缀与其前身之间最长公共前缀的信息,并密切关注累积子字符串计数。所以我知道对于给定的k 大于最后一项的累积子字符串计数,这是一个无效的查询。

这对于问题定义中给出的约束的小输入和随机大输入非常有效,最多有 50 个长度为 2000 的字符串。我能够通过 7 个案例中的 4 个,并且非常惊讶我没有得到它们。

所以我去寻找瓶颈,它击中了我。给定大量这样的输入

anananananananana.....ananana
bkbkbkbkbkbkbkbkb.....bkbkbkb

对第 k 个最小子字符串的查询仍然像预期的那样快 但不是我预处理排序集的方式...我计算集合元素之间最长公共前缀的方式是效率不高且线性 O(m),像这样,我做了最天真的事情,期望它足够好:

m = anananan
n = anananana

Start at 0 and find the point where `m[i] != n[i]`

之所以这样,是因为后缀和他的前身可能没有关系(即来自不同的输入字符串),所以我想我只能使用蛮力。

这是当时的问题以及我最终将问题减少到的地方。给定一个按我上面描述的方式按字典顺序排序的后缀列表(由多个字符串组成):

什么是计算最长公共前缀数组的有效方法?

接下来的子问题是,我的方法是否完全不合时宜?如果是这种情况,请提出进一步的调查途径。

脚注,我不想看到已实现的算法,我不介意被告知去阅读有关该主题的某某书籍或资源,因为无论如何我在尝试这些挑战时都会这样做.

接受的答案将引导我走上正确的道路,或者在失败的情况下;教我如何在更广泛的意义上解决这些类型的问题的东西,一本书或其他东西

【问题讨论】:

    标签: string algorithm similarity suffix-array


    【解决方案1】:

    阅读

    我会推荐这个tutorial pdf from Stanford

    本教程解释了一个简单的 O(nlog^2n) 算法,它使用 O(nlogn) 空间来计算后缀数组和中间结果矩阵。中间结果矩阵可用于计算 O(logn) 中两个后缀之间的最长公共前缀。

    提示

    如果您想尝试自己开发算法,关键是根据字符串的 2^k 长前缀对字符串进行排序。

    来自教程:

    让我们用 A(i,k) 表示从位置 i 开始的长度为 2^k 的 A 的子序列。 A(i,k) 在 A(j,k) 个子序列 (j=1,n) 的排序数组中的位置保存在 P(k,i) 中。

    使用矩阵 P,可以从最大的 k 向下迭代到 0,并检查 A(i,k) = A(j,k)。如果两个前缀相等,则找到长度为 2^k 的公共前缀。我们只剩下更新 i 和 j,将它们都增加 2^k 并再次检查是否有更多常见的前缀。

    【讨论】:

    • 这个 pdf 真的很棒,链接被访问了 :D。您能否评论来自不同源字符串的后缀的要求,如果它确实涵盖了这种情况,而不是(引自pdf)“给定字符串A的两个后缀......”。由于某种原因,我无法理解这一点。
    • 在问题6的描述中解释了处理不同源字符串的简单方法。基本上给每个字符串添加一个唯一的结束字符,将它们连接成一个单独的长字符串,并使用标准的后缀数组算法.我认为这应该适用于您的情况,尽管正确获取详细信息可能会很棘手!
    • 这是一个惊人的前景,我今天一边思考一边思考,但我说服自己这行不通。我会用笔和纸观察一下它会是什么样子。
    • 无法表达我多么感激报告我通过了 7/7 个测试用例。你是对的,用唯一字符连接字符串(我拿了 $)给了我一种有效生成最长公共前缀数组的方法。在那之后让细节正确但有可能并且在恒定的时间内变得很棘手。
    • 实际上,您发明了一种比我建议的更好的方法。我的意思是你为每个字符串使用不同的唯一字符(即#、$、@) - 很好地让它与单个唯一字符一起工作!
    猜你喜欢
    • 2018-05-29
    • 2020-04-28
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多