【发布时间】:2017-01-19 07:48:24
【问题描述】:
我有一大组 (50k-100k) 字符串 mystrings。 mystrings 中的某些字符串可能是其他字符串的确切子字符串,我想折叠这些字符串(丢弃子字符串并只保留最长的字符串)。现在我正在使用一种简单的方法,它具有O(N^2) 的复杂性。
unique_strings = set()
for s in sorted(mystrings, key=len, reverse=True):
keep = True
for us in unique_strings:
if s in us:
keep = False
break
if keep:
unique_strings.add(s)
哪些数据结构或算法可以使这项任务更容易,并且不需要O(N^2) 操作。库还可以,但我需要保持纯 Python。
【问题讨论】:
-
更多 Pythonic,丢弃
keep布尔值并在for循环上使用else子句(当然不会改变时间复杂度)python-notes.curiousefficiency.org/en/latest/python_concepts/… -
@Chris_Rands 你能演示一下吗?一旦找到匹配项,就没有理由继续迭代内部 for 循环,因此中断。但是,一旦我们退出内部循环,我们不知道我们是否因为找到匹配项而中断,或者我们是否刚刚完成迭代。也许我遗漏了一些东西,但我认为这是实现这种(诚然天真的)方法的最简洁和高效的方式。
-
您保留
break,只需将if keep:替换为else:(相同的缩进)并删除所有带有keep的行。else子句仅在break不发生时执行。如果您不熟悉 for-else 构造,请阅读我上面链接的文章 -
酷!关键字太常见了,我忽略了循环的语义含义。
-
其实再看一遍,你可以用
any()或者all()代替,比如if not any(s in us for us in unique_strings): unique_strings.add(s)会像break一样短路
标签: python string set substring