Мне нужно сделать программу, которая берет на вход файл со словарем и произвольную строку, а затем выводит все комбинации слов из этого словаря, составляющие анаграммы заданной строки. Например, используя 100 самых популярных слов английского языка и строку "i not work"
, я должен получить что-то вроде [' on it work', ' into work', ' not i work', ' know or it', ' work it no', ' to work in']
, что я и делаю.
Проблема в том, что моя программа слишком неэффективна: при 100 словах в словаре практический предел составляет 7 символов для длины строки, все после этого занимает слишком много времени. Я пытался искать различные алгоритмы, связанные с этим вопросом, но безрезультатно.
Вот как я ищу анаграммы:
def sortstring(string):
return ''.join(sorted(string))
def simplify(all_strings):
possible_strings = defaultdict(list)
for string in all_strings:
possible_strings[sortstring(string).strip()].append(string)
return possible_strings
def generate(database, length,curstring="", curdata=set()):
if len(curstring.replace(" ", "")) > length:
return set()
if len((curstring).replace(" ", "")) == length:
return curdata.union(set([curstring]))
for i in database:
if len((curstring+i).replace(" ", "")) <= length:
curdata = curdata.union(generate(database.difference(set([i])),
length, curstring+" "+i, curdata))
database = database.difference(set([i]))
return curdata
def analyse(database, input_string):
cletters = countstring(input_string)
strings = simplify(generate(database, cletters))
data = list()
sorted_string = sortstring(input_string).strip()
if sorted_string in strings.keys():
data = strings[sorted_string]
return len(strings.values()), data
def countstring(string):
a = countletters(string)
return sum(a.values())
def countletters(string):
result = {}
for i in ascii_lowercase:
result[i] = string.count(i)
return result
Может ли кто-нибудь предложить способ улучшить это? Хотя я полагаю, что алгоритм, который я использовал, должен быть полностью исключен, учитывая, что сложность кажется слишком высокой из-за того, насколько он медленный. На всякий случай: программа должна быть достаточно производительной, чтобы поддерживать словари из десятков тысяч слов и строк до десятков символов. Это намного лучше, чем то, что я сделал.