【问题标题】:What is the fastest algorithm: in a string list, remove all the strings which are substrings of another string [Python (or other language)]什么是最快的算法:在字符串列表中,删除作为另一个字符串的子字符串的所有字符串 [Python(或其他语言)]
【发布时间】:2020-04-16 22:44:11
【问题描述】:

有一个字符串列表,例如["abc", "ab", "ad", "cde", "cde", "de", "def"] 我希望输出为 ["abc", "ad", "cde", "def"]

"ab" 被删除,因为它是 "abc" 的子字符串 "cde" 被删除,因为它是另一个 "cde" 的子字符串 “de”被删除,因为它是“def”的子字符串

最快的算法是什么?

我有一个蛮力方法,就是O(n^2),如下:

def keep_long_str(str_list):
    str_list.sort(key = lambda x: -len(x))
    cleaned_str_list = []
    for element in str_list:
        element = element.lower()
        keep_element = 1
        for cleaned_element in cleaned_str_list:
            if element in cleaned_element:
                keep_element = 0
                break
            else:
                keep_element = 1
        if keep_element:
            cleaned_str_list.append(element)
    return cleaned_str_list

【问题讨论】:

  • * 删除,错字见谅,不知道大家修改问题
  • 点击问题下方的edit 链接。标题位于顶部的单独文本框中。
  • 请重复intro tour。如果你表现出你的努力,你会得到更好的回应:发布你的代码,描述复杂性(例如 O(n^2)),并且也许建议 - 一般来说 - 它可能是怎样的改进。
  • “最快的方法是什么”通常翻译为“我不知道该怎么做;给我一些代码?”
  • 如果输入列表是["cde", "de"],是否会删除"de"

标签: python algorithm


【解决方案1】:
strings = ["abc", "ab", "ad", "cde", "cde", "de", "def"]
unique_strings = []

for s in strings: 
     if all(s not in uniq for uniq in unique_strings):
         unique_strings.append(s)

运行此代码后,unique_strings 等于 ['abc', 'cde', 'def', 'ad']

注意:这可能不是最快的方法,但它是一个简单的解决方案。

【讨论】:

  • 如果较短的字符串出现在较长的字符串之前,strings = ["ab", "abc", "ad", "cde", "cde", "de", "def"],则结果为{'abc', 'ad', 'def', 'ab', 'cde'}。这可以通过首先对较长的字符串进行排序来纠正,strings.sort(key=len, reverse=True)
  • 为什么在这里使用集合而不是列表?您只使用集合进行迭代和添加,因此列表应该更快。顺便说一下,这个解也是O(n^2)。
  • 谢谢@kaya3!用您的建议更新了答案。
【解决方案2】:

我查看了 Jack Moody 和 Chris Charley 的答案,但仍然不喜欢使用 all,因为 any 可能会在第一次出现超级字符串时跳出循环,所以想出了这个改动:

strings = ["abc", "ab", "ad", "cde", "cde", "de", "def"]
unique_strings = []
for s in sorted(strings, reverse=True):  # Largest first 
    if not any(s in uniq for uniq in unique_strings):
        unique_strings.append(s)
print(unique_strings)  # ['def', 'cde', 'ad', 'abc']

我认为没有必要对字符串len 进行明确排序,因为无论如何它都是字符串比较的一部分。干杯:-)

【讨论】:

  • all 也短路了。
  • 如果测试列表的构造类似于strings = ["ab", "abc", "ad", "cde", "cde", "de", "def"],那么结果将是{'abc', 'ad', 'def', 'ab', 'cde'}ab 在结果中,不应该出现在结果中。所以,我认为仍然有必要按长度对位进行排序。
  • 嗨,克里斯,我使用了您的初始订单,并使用我的代码得到了与以前相同的结果,因为排序使代码不依赖于原始订单。在循环工作时,由于排序,字符串“abc”在字符串“ab”之前被考虑,并且因为“ab”是一个子字符串,它不会被添加到结果中。
  • 好吧,我错过了你帖子中的排序。
猜你喜欢
  • 2012-08-31
  • 1970-01-01
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2021-04-07
  • 2023-03-08
相关资源
最近更新 更多