Вот функция с некоторыми basi c короткозамкнутыми логами c, чтобы сделать все это дело более производительным:
def remove_substrings(words):
output_words = []
for ind, word in enumerate(words):
if not any(word in output_word for output_word in output_words):
if not any(word in words[i] for i in range(ind + 1, len(words))):
output_words.append(word)
return output_words
words = ['rick','rick sanchez','morty','morty smith sanchez','morty smith']
print(remove_substrings(words))
print(remove_substrings(["rick"] * 2))
print(remove_substrings(["rick"] * 20000))
print(remove_substrings([*["rick"] * 10000, *["morty"] * 10000]))
print(remove_substrings([w for _ in range(10000) for w in ["rick", "morty"]]))
print(list(map(len, remove_substrings(["a" * i for i in range(10000)]))))
print(list(map(len, remove_substrings(["rick" * i for i in range(10000)]))))
print(list(map(len, remove_substrings(["a" * (10000 - i) for i in range(10000)]))))
print(list(map(len, remove_substrings(["rick" * (10000 - i) for i in range(10000)]))))
Это имеет ожидаемый результат,
['rick sanchez', 'morty smith sanchez']
['rick']
['rick']
['rick', 'morty']
['rick', 'morty']
[9999]
[39996]
[10000]
[40000]
в вполне разумное время.
Его поведение в крайнем случае, когда у вас есть повторяющийся элемент, состоит в том, чтобы сохранить один из этого элемента, который, я думаю, является последовательным способом поведения. Вы можете изменить это, чтобы вести себя по-другому, если хотите.
Идея в том, что если мы ранее отклонили слово, нам не нужно будет снова его рассматривать, так как оно было отклонено на основании либо слово, которое мы уже пометили как правильное, или слово после него, оба из которых имеют это слово в качестве подстроки, поэтому они оба будут работать над отклонением других невозможных кандидатов.
Важно, что использование Функция any
с выражениями-генераторами также означает, что как только она находит слово, под которым находится текущее слово, она прекращает поиск таких слов. Такое короткое замыкание делает его еще быстрее.
Я не сомневаюсь, что можно сделать гораздо больше оптимизаций. Почти наверняка есть какая-то древовидная структура, которая в некоторой степени уменьшает временную сложность, но я думаю, что это неплохое начало.