Python 从字符串数组中删除子字符串的最有效方法

Python 从字符串数组中删除子字符串的最有效方法,python,algorithm,performance,substring,Python,Algorithm,Performance,Substring,注意:这个问题与Python没有特别的关系。我只是用它来代替这里的伪代码 给定一个数组A包含平均长度M的N字符串,我想创建一个新的数组B,该数组只包含A中不属于A中任何其他字符串的子字符串(或相同副本)。以下是一个例子: A = [ 'foo', 'bar', 'foobar', 'foobar' ] B = [ 'foobar' ] 就时间复杂性而言,我特别寻找最有效的方法。这种天真的方法看起来是这样的 B = [] for i in range(0, len(A)): noSubs

注意:这个问题与Python没有特别的关系。我只是用它来代替这里的伪代码

给定一个数组
A
包含平均长度
M
N
字符串,我想创建一个新的数组
B
,该数组只包含
A
中不属于
A
中任何其他字符串的子字符串(或相同副本)。以下是一个例子:

A = [ 'foo', 'bar', 'foobar', 'foobar' ]
B = [ 'foobar' ]
就时间复杂性而言,我特别寻找最有效的方法。这种天真的方法看起来是这样的

B = []
for i in range(0, len(A)):
    noSubstring = True
    for j in range(i + 1, len(A)):
        if A[i] in A[j]:
            noSubstring = False
            break
    if noSubstring:
        B.append(A[i])
时间复杂度为
O(N^2*M^2)
。我能做些什么来加快速度吗


我一直在考虑使用专用的数据结构来高效地编码和重用字符串序列。例如,如果我想删除仅作为数组中另一个字符串前缀的字符串,我可以创建一个trie/前缀树(
O(N*M)
),然后收集所有叶元素(另一个
O(N*M)
)。然而,到目前为止,我未能将这种方法应用于更一般的子字符串问题。

首先消除所有重复项。通过在迭代数据时使用哈希表,并存储已经看到的字符串,这是相当容易做到的。(如果您担心哈希表的最坏情况,可以使用or排序和迭代来过滤重复)

过滤掉所有重复项后,为所有剩余字符串创建一个。
创建后缀树后,对于每个字符串,检查它是否作为某个字符串的后缀存在,而该字符串本身不是后缀。这是通过遵循后缀树上从根到字符串末尾的路径来完成的,如果您唯一的选项是完全相同的字符串,则它不是子字符串(否则-它是)

时间复杂性:

  • 过滤掉重复:O(n*m)
  • 理论上构建后缀树O(n*m),但实际上是在
    O(n*mlog(m))
    中完成的
  • 检查每个字符串是否为O(m),然后重复检查
    n
    字符串是否为O(nm)

总的复杂度是
O(n*mlog(m))

您可能希望对
a
使用
集,因为您无论如何都不希望重复。下面是一个问题,答案是:在naiva实现中,如果a[i]比a[j]长,您可以避免执行字符串搜索
过滤掉重复数据
-哈希表方法理论上是O(n),对吗?@thefourtheye
O(nm)
,您需要读取所有字符串,每个字符串都需要
O(m)
时间。如果你担心最坏的散列行为,也可以通过排序,甚至是用字符串创建一个trie来完成。它会将检查阶段从O(nm)增加到O(nm log m),但由于构造本身已经非常复杂,所以不会有问题。