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