Меня интересуют попытки и DAWG (прямой ациклический график слов), я много читал о них, но не понимаю, как должно выглядеть выходное дерево или файл DAWG.
- Должно ли дерево быть объектом вложенных словарей? Где каждая буква делится на буквы и так далее?
- Будет ли поиск, выполняемый в таком словаре, быстрым, если есть 100 000 или 500 000 записей?
- Как реализовать блоки слов, состоящие более чем из одного слова, разделенных
-
пробелом или символом? - Как связать префикс или суффикс слова с другой частью структуры? (для DAWG)
Я хочу понять лучшую структуру вывода , чтобы понять, как ее создать и использовать.
Я также был бы признателен, каким должен быть результат DAWG вместе с trie .
Я не хочу видеть графические представления с пузырьками, связанными друг с другом, я хочу знать выходной объект, когда набор слов превращается в попытки или DAWG.
Ответы:
По сути, Unwind верен тем, что есть много разных способов реализовать дерево; а для большого масштабируемого дерева вложенные словари могут стать громоздкими или, по крайней мере, неэффективно занимать место. Но поскольку вы только начинаете, я думаю, что это самый простой подход; вы можете написать простой код
trie
всего в несколько строк. Во-первых, функция для построения дерева:Если вы не знакомы с ним
setdefault
, он просто ищет ключ в словаре (здесьletter
или_end
). Если ключ присутствует, он возвращает связанное значение; если нет, он присваивает этому ключу значение по умолчанию и возвращает значение ({}
или_end
). (Это похоже на версию,get
которая также обновляет словарь.)Затем функция для проверки, есть ли слово в дереве:
Я оставлю вам вставку и удаление в качестве упражнения.
Конечно, предложение Unwind было бы не намного сложнее. Может быть небольшой недостаток скорости в том, что для поиска правильного подузла потребуется линейный поиск. Но поиск будет ограничен количеством возможных символов - 27, если мы включим
_end
. К тому же, как он предлагает, создание огромного списка узлов и доступ к ним по индексу ничего не даст; вы можете просто вложить списки.Наконец, я добавлю, что создание ориентированного ациклического графа слов (DAWG) было бы немного сложнее, потому что вы должны обнаруживать ситуации, в которых ваше текущее слово имеет суффикс с другим словом в структуре. Фактически, это может быть довольно сложно, в зависимости от того, как вы хотите структурировать DAWG! Возможно, вам придется кое-что узнать о расстоянии Левенштейна, чтобы понять это правильно.
источник
dict.setdefault()
(он недостаточно используется и малоизвестен), отчасти потому, что он помогает предотвратить ошибки, которые слишком легко создать с помощьюdefaultdict
(где вы не получитеKeyError
для несуществующих ключей при индексировании). Единственное, что сделало бы его пригодным для производственного кода, - это использовать_end = object()
:-)Посмотри на это:
https://github.com/kmike/marisa-trie
Вот сообщение в блоге компании, успешно использующей marisa trie:
https://www.repustate.com/blog/sharing-large-data-structure-across-processes-python/
Существует также пара реализаций чистого python, хотя, если вы не находитесь на ограниченной платформе, вы бы хотели использовать реализацию с поддержкой C ++, описанную выше, для лучшей производительности:
источник
Вот список пакетов Python, реализующих Trie:
источник
Изменено
senderle
с помощью метода (см. Выше). Я обнаружил, что Pythondefaultdict
идеально подходит для создания дерева префиксов или дерева префиксов.источник
Нет никакого «следует»; тебе решать. Различные реализации будут иметь разные характеристики производительности, для реализации, понимания и исправления потребуется разное количество времени. На мой взгляд, это типично для разработки программного обеспечения в целом.
Я бы, вероятно, сначала попробовал создать глобальный список всех созданных на данный момент узлов trie и представить дочерние указатели в каждом узле в виде списка индексов в глобальном списке. Мне кажется, что наличие словаря только для представления дочерних ссылок кажется слишком тяжелым.
источник
Если вы хотите, чтобы TRIE был реализован как класс Python, вот что я написал после прочтения о них:
источник
Определите Trie:
Создать Trie:
Уважать:
Тест:
источник
True
только для всего слова, но не для префикса, для изменения префиксаreturn '_end' in curr
наreturn True
В этой версии используется рекурсия
Вывод:
источник
Вне
источник
Класс Python для Trie
Структура данных Trie может использоваться для хранения данных,
O(L)
где L - длина строки, поэтому для вставки N строк временная сложность будет заключаться вO(NL)
том, что строку можно искать вO(L)
только для удаления.Можно клонировать с https://github.com/Parikshit22/pytrie.git
Код Oputpt
Правда
Ложь
[ 'Minakshi', 'Минхадж']
7
Minakshi
minhajsir
Pari
Парикшит
Shubh
Shubham
shubhi
источник