У меня есть большой (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' boolean и вместо этого используйте' else' предложение в цикле 'for' (не будет изменять временную сложность) http://python-notes.curiousefficiency.org/en/ last/python_concepts/break_else.html –
@Chris_Rands Могли бы вы продемонстрировать? Нет причин продолжать повторение цикла внутреннего цикла после того, как будет найдено совпадение, таким образом, разрыв. Но тогда, как только мы выйдем из внутреннего цикла, мы не знаем, разразились ли мы, потому что совпадение было найдено или если мы только закончили итерацию. Может быть, я что-то упустил, но я думаю, что это самый лаконичный и эффективный способ реализовать этот (по общему признанию наивный) подход. –
Вы сохраняете 'break', просто замените' if keep: 'на' else: '(тот же отступ) и удалите все строки с' keep'. Предложение 'else' выполняется только тогда, когда' break' не происходит. прочитайте статью, связанную выше, если вы не знакомы с конструкцией for-else –