Python:删除集合中字符串的较长子字符串

时间:2019-03-05 01:37:14

标签: python python-3.x string for-loop set

我的字符串很长。在这个字符串中,我创建了一个大的子字符串集,其中每个元素可能是该集中其他子字符串的子子字符串。我正在尝试从原始集合中创建仅包含最短子串的集合。到目前为止,这是我尝试的解决方法。

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)

我正在创建原始集的副本,并依次遍历setAsetB的元素。如果这些元素之一是另一个元素的子字符串,我将丢弃较长的元素。我的解决方案的运行时间随着setA元素的增加(由于使用嵌套循环)而大大增加。有没有更低时间复杂度的解决方案?

2 个答案:

答案 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