Я делаю мобильное приложение для поиска анаграмм и частичных совпадений. Мобильность важна, потому что вычислительная мощность невелика, а эффективность является ключевым фактором.
Алгоритм принимает любое количество букв, включая повторы, и находит самые длинные слова, составленные из его букв, используя каждую букву только один раз. Я также заинтересован в быстром нахождении лучших результатов, и на самом деле меня не интересуют днища (более короткие), пока N встречается. Например:
STACK => stack, tacks, acts, cask, cast, cats…
Я немного погуглил и нашел несколько алгоритмов, и я нашел один, который, как мне показалось, будет эффективным, но не настолько эффективным, как хотелось бы.
У меня есть готовый словарь поиска, который сопоставляет отсортированный ключ с реальными словами, которые генерируют этот ключ.
"aelpp" => ["apple", "appel", "pepla"]
Далее я разбил каждый словарь на разные по длине ключа. Таким образом, ключи длиной 5 букв находятся в одном словаре, а ключи длиной 6 - в другом. Каждый из этих словарей находится в массиве, в котором индекс - это длина ключей, найденных в словаре.
anagramArray[5] => dictionary5
dictionary5["aelpp"] => ["apple", "appel", "pepla"]
Мой алгоритм начинается с ввода входного слова "lappe
" и сортирует его:
"lappe" => "aelpp"
Теперь для каждого словаря, содержащего не более 5 букв, я делаю сравнение, чтобы вытащить его. Вот псевдокод:
word = input.sort
for (i = word.length; i > 0; i--)
dictionaryN = array[i]
for (key in dictionaryN)
if word matches key
add to returnArray
end
end
if returnArray count > N
break
end
end
returnArray.sort by longest word, alphabetize
В словаре всего около 170 000 слов, но поиск занимает 12 секунд для 12-буквенного ввода. Мой метод match
делает регулярное выражение из ключа:
"ackst" => /a.*c.*k.*s.*t.*/
, например 4-буквенный ключ, например acst
(действует), будет соответствовать ackst
(стек), поскольку:
"ackst" matches /a.*c.*s.*t.*/
Я видел, как другие приложения делают то же самое за гораздо меньшее время, и мне интересно, является ли мой подход ненужным или просто нуждается в настройке.
Как получить максимальную вычислительную эффективность для генерации лучших N анаграмм из слова, отсортированного по максимальной длине?