我的字符串很长。在这个字符串中,我创建了一个大的子字符串集,其中每个元素可能是该集中其他子字符串的子子字符串。我正在尝试从原始集合中创建仅包含最短子串的集合。到目前为止,这是我尝试的解决方法。
string = 'ABAAABAAB'
setA = {'ABAAAB', 'BAAAB', 'AAAB', 'AAB'}
setB = setA.copy()
setC = setA.copy()
for s1 in setA:
len1 = len(s1)
for s2 in setB:
len2 = len(s2)
if s1 in s2 and len2 > len1:
setC.discard(s2)
我正在创建原始集的副本,并依次遍历setA
和setB
的元素。如果这些元素之一是另一个元素的子字符串,我将丢弃较长的元素。我的解决方案的运行时间随着setA
元素的增加(由于使用嵌套循环)而大大增加。有没有更低时间复杂度的解决方案?
答案 0 :(得分:3)
您可以从最短的字符串到最长的字符串遍历setA
,只有在setC
中没有可能的子字符串的情况下,才能将给定的字符串添加到setC
。您可以通过以下方式从字符串中生成所有可能的子字符串:将起始索引遍历字符串的长度,然后将子字符串的大小从1迭代至当前起始索引的字符串的剩余长度,然后使用起始索引和用来分割字符串的子字符串长度:
setC = set()
for s in sorted(setA, key=len):
if not any(s[i: i + n + 1] in setC for i in range(len(s)) for n in range(len(s) - i)):
setC.add(s)
setC
变为:
{'AAB'}
从解决方案的 O(n ^ 2)到 O(n log n),这将提高整体时间复杂度。
答案 1 :(得分:1)
要使@blhsing发布的子字符串搜索算法更易于阅读,您可以将步骤分为自己的循环。只是不在一行内,这是相同的逻辑。
setC = set()
sortedList = sorted(setA, key=len)
for substring in sortedList:
if not substring_in_set(substring, set3):
setC.add(substring)
# Checks whether the subtrings is in the set
# and returns True or False
def substring_in_set(substring, set):
for i in range(len(substring)):
for n in range(len(substring) - i):
if substring[i: i + n + 1] in set:
return True
return False