Автор оригинала: FreeCodeCapm Team.
Джулия Гейст
TRIE (выраженная попытка) получает свое имя из Re Три Val – его структура делает его звездным сопоставлением алгоритмом.
Контекст
Write your own shuffle method to randomly shuffle characters in a string.
Use the words text file, located at /usr/share/dict/words, and your shuffle method to create an anagram generator that only produces real words.
Given a string as a command line argument, print one of its anagrams.
Я был представлен этой проблемой на этой неделе в Сделать школу академии продукта Отказ
Слова в текстовом файле разделены новыми строками. Его форматирование делает его намного легче поставить слова в структуру данных. На данный момент я храним их в списке – каждый элемент является одним словом из файла.
Один подход к этой проблеме является:
- случайное переместите символы в строке
- Затем проверьте это против всех слов, которые были в /usr/share/dict/words чтобы убедиться, что это настоящее слово.
Тем не менее, этот подход требует, чтобы я проверял, что случайно перетасовываемые символы в новой строке совпадают с одним из 235 887 слов в этом файле – это означает 235 887 Операции для каждый строка что я хочу проверить как настоящее слово.
Это было недопустимое решение для меня. Я впервые посмотрел библиотеки, которые уже были реализованы, чтобы проверить, будут ли слова на языке, и нашли PENENCANT Отказ Я впервые завершил задачу, используя библиотеку, в нескольких строках кода.
def generateAnagram(string, language="en_US"): languageDict = enchant.Dict(language) numOfPossibleCombinationsForString = math.factorial(len(string)) for i in range(0, numOfPossibleCombinationsForString): wordWithShuffledCharacters = shuffleCharactersOf(string)
if languageDict.check(wordWithShuffledCharacters): return wordWithShuffledCharacters return "There is no anagram in %s for %s." % (language, string)
Использование нескольких библиотечных функций в моем коде было быстрое и простым решением. Тем не менее, я не узнал много, найдя библиотеку, чтобы решить эту проблему для меня.
Я был уверен, что библиотека не использовала подход, который я упоминал ранее. Мне было любопытно и вырыто по исходному коду – я нашел TRIE.
Три
TRIE хранит данные в «шагах». Каждый шаг – узел в Три.
Хранение слова – это идеальное использование для этого вида дерева, поскольку есть конечное количество букв, которые могут быть собраны, чтобы сделать строку.
Каждый шаг или узел, на языке TRIE будет представлять одну букву слова. Шаги начинают откладывать, когда порядок букв расходится от других слов в Три, или когда слово заканчивается.
Я создал TRE из каталогов на своем рабочем столе к визуализировать наступая через узлы. Это TRIE, которая содержит два слова: Apple и App.
Обратите внимание, что конец слова обозначается с помощью «$». Я использую «$», потому что это уникальный характер, который не присутствует ни в каком языке на любом языке.
Если бы я мог добавить слово «апертуру» к этому TRIE, я бы петлю по буквам в словом «апертуре», одновременно наступая вниз по узлам в Три. Если письмо существует как ребенок текущего узла, уйдите в него. Если письмо не существует в качестве ребенка текущего узла, создайте его, а затем пойти в него. Чтобы визуализировать эти шаги с использованием моих каталогов:
Во время перехода TRIE, первые два буквы «диафрагмы» уже присутствуют в TRIE, поэтому я шагаю в эти узлы.
Третье письмо, «E», однако, не является ребенком узла «P». Создан новый узел для представления буквы «E», отделение от других слов в TRIE. Новые узлы для писем, которые следуют также.
Для генерации TRIE из файла слов этот процесс произойдет для каждого слова, пока все комбинации для каждого слова не будут сохранены.
Возможно, вы думаете: «Подождите, не займет действительно много времени, чтобы создать TRIE из этого текстового файла с 235 887 слов в нем? Какова точка зацикливания на каждый персонаж в каждом числе?»
Да, итерация по каждому характеру каждого слова для генерации TRIE займет некоторое время. Тем не менее, время, необходимое для создания TRIE, является оно того стоит – Потому что, чтобы проверить, существует ли слово в текстовом файле, он больше всего занимает, столько операций, как Длина самого слова Отказ Намного лучше чем операции 235 887, которые он собирался взять раньше.
Я написал простейшую версию TRIE, используя вложенные словари. Это не самый эффективный способ реализации одного, но это хорошее упражнение, чтобы понять логику позади TRIE.
endOfWord = "$"
def generateTrieFromWordsArray(words): root = {} for word in words: currentDict = root for letter in word: currentDict = currentDict.setdefault(letter, {}) currentDict[endOfWord] = endOfWord return root
def isWordPresentInTrie(trie, word): currentDict = trie for letter in word: if letter in currentDict: currentDict = currentDict[letter] else: return False return endOfWord in currentDict
Вы можете увидеть мой решение Для генератора анаграммы на моем Github. Поскольку исследуя этот алгоритм, я решил сделать этот блог пост один из многих – каждый пост, охватывающий один алгоритм или структуру данных. Код доступен на моем Алгоритмы и структуры данных Reppo – звезда, чтобы оставаться в курсе!
Следующие шаги
Я предлагаю проверить Ray Wenderlich’s TRIE REPO Отказ Хотя написано в SWIFT, это ценный источник для объяснений различных алгоритмов.
Подобно TRIE (но более эффективному памяти) является деревом суффикса или радикса. Короче, вместо того, чтобы хранить один символы на каждом узле, сохраняется конец слова, его суффикс, хранятся, и пути созданы относительно.
Тем не менее, Radix более сложный для реализации, чем ТРИ. Я предлагаю взглянуть на Ray Wenderlich’s Radix Reppo если тебе интересно.
Это первый пост моего алгоритма и серии структур данных. В каждом посте я представляю проблему, которая может быть лучше решена с помощью алгоритма или структуры данных, чтобы иллюстрировать саму алгоритму/структуру данных.
Звезда моя алгоритмы репо на Github и следуй за мной на Twitter Если вы хотели бы следовать!
Вы получили ценность, прочитав эту статью? Нажмите здесь Поделиться этим в Twitter! Если вы хотите увидеть так чаще, следуйте за мной на Medium и подпишитесь на новостную рассылку один раз в месяц. Не стесняйтесь Купи мне кофе тоже.