【问题标题】:Python: Removing longer substrings of a string within a setPython:删除集合中字符串的较长子字符串
【发布时间】:2019-07-26 09:53:07
【问题描述】:

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

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 的元素增加,我的解决方案的运行时间大大增加。有没有时间复杂度更低的解决方案?

【问题讨论】:

  • 你能在这个例子的最后展示一下你想在setC 中成为什么吗?我最初对如何提高效率的想法是使用存储在列表中的setA 的排序版本(可能是字符串的长度?),而不是将其保持为一个集合(未排序)。
  • 当然,setC 将是 {'AAB'}。但是我不确定创建一个列表是否可行,因为我首先从另外两个集合的联合中创建了setA。
  • 从@blhsing 发布的anwer 中,您可以使用sorted() 函数对集合进行排序并将其转换为列表。

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


【解决方案1】:

您可以从最短的字符串到最长的字符串遍历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)。

【讨论】:

  • 非常感谢您的回答。您认为您可以详细说明一下您的代码如何确定字符串的所有子字符串都不在setC 中吗?
  • 很高兴能提供帮助。我已经对如何生成所有可能的子字符串添加了解释。希望这会有所帮助。
【解决方案2】:

为了使@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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 2022-08-19
    • 2019-09-08
    • 1970-01-01
    相关资源
    最近更新 更多