【问题标题】:string match in PythonPython中的字符串匹配
【发布时间】:2013-08-10 19:52:17
【问题描述】:

我在列表中存储了 300K 个字符串,每个字符串的长度在 10 到 400 之间。我想删除其他字符串的子字符串(长度较短的字符串更有可能成为其他)。

目前,我首先根据长度对这 300K 字符串进行排序,然后使用下面的方法。

sorted_string = sorted(string_list, key=length, reverse=True)
for item in sorted_string
    for next_item in sorted_string[sorted_string.index(item)+1:]
        if next_item in item:
            del sorted_string[sorted_string.index(next_item)]

这个方法的运行时间是O(n^2)。由于我有 300K 字符串,我对这种方法并不满意。

我试图将这些排序的字符串分成不同的块,并使用多处理来计算每个块。我的第一个想法是将前 10K 放在第一个块中,然后将接下来的 10K 放在第二个块中,等等。但是这样,每个块中的字符串具有相似的长度,并且它们可能不会是同一块中其他字符串的子串。所以这不是一个好的划分策略。

有什么好主意吗?

编辑:这些字符串代表DNA序列,只包含'g'、'c'、't'和'a'

更新

我尝试使用https://github.com/kvh/Python-Suffix-Tree 中的代码构建后缀树。该程序基于Ukkonen's algorithm 构建后缀树。

连接字符串的总长度约为 90,000,000。这是一个很大的数字。该程序已运行半小时,仅处理了约 3,000,000 (1/30) 个字符。我对这个程序不满意。

有没有其他的后缀树构建算法可以处理这个大字符串?

【问题讨论】:

  • 你有没有猜测你会发现多少个字符串是其他字符串的子字符串?这可能会影响最有效的方法
  • 另外,这些字符串的性质是什么?它们是句子吗?如果是,它们是用什么语言编写的?它们只是随机字符吗?它们是 dna 的表示形式,因此只包含“g”、“t”、“c”和“a”吗?
  • @RobWatts 是的,它们是 DNA 序列,仅包含“g”“c”“t”“a”。而且我不知道有多少字符串是子字符串。
  • 由于您的字母表很小,因此更有理由使用后缀树。 :D

标签: python algorithm string-matching


【解决方案1】:

您可以使用suffix tree。它会让你达到 O(mn),其中 m 是字符串的长度。它仍然是二次的,但由于 m

These lecture notes 提供了一个很好的可视化解释,说明如何使用后缀树来查找子字符串。

【讨论】:

  • 如何使用后缀树来查找要比较的两个字符串?我所能看到的是,一旦你决定比较哪两个字符串,这将如何加快速度
  • 如果一个单词是任何单词的子串,那么它就是一个子串,因此基于所有连接在一起的单词构建一个后缀树(它们之间有一个分隔符)。这应该采用 O(nm),因为新的字符串长度是 n*m。然后,针对后缀树运行每个单词,这也需要 O(nm),因为每次搜索需要 O(m) 时间。
  • @kevmo314 所以我猜对于每个单词,如果我们能找到两次以上,那么这个单词就是一个子字符串,因为我们可以在后缀树中找到每个单词至少一次,对吧?
  • 是的,这是最直接的方法。可能有一种更聪明的方法可以做到这一点,而无需检查每个单词两次。例如,如果您找到的“子字符串”由两个分隔符限定,那么它是原始字符串而不是子字符串,但前者可能更容易实现。
【解决方案2】:

这是一个非常酷且非常有趣的问题。我研究过子集种子算法,而且已经有不少了。

您听说过 BLAST 算法吗? http://blastalgorithm.com/ 一个界面:http://blast.ncbi.nlm.nih.gov/

【讨论】:

    猜你喜欢
    • 2020-05-26
    • 2021-08-25
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 2019-06-26
    • 2016-06-09
    • 1970-01-01
    相关资源
    最近更新 更多