Бор — различия между версиями
ExileHell (обсуждение | вклад) (→Построение) |
ExileHell (обсуждение | вклад) (→Построение) |
||
| Строка 7: | Строка 7: | ||
==Построение== | ==Построение== | ||
| + | ===Обозначения=== | ||
Введем следующие обозначения: | Введем следующие обозначения: | ||
*<tex>P = \{P_1,\ldots,P_k\} </tex> — набор строк, называемый словарем; | *<tex>P = \{P_1,\ldots,P_k\} </tex> — набор строк, называемый словарем; | ||
*<tex>n = \sum_{i=1}^{k|P_i|}\limits |P_i|</tex>. | *<tex>n = \sum_{i=1}^{k|P_i|}\limits |P_i|</tex>. | ||
| − | + | ===Алгоритм=== | |
Непосредственно построение: | Непосредственно построение: | ||
#Начинаем с [[Дерево, эквивалентные определения | дерева]] из одной вершины (корня). | #Начинаем с [[Дерево, эквивалентные определения | дерева]] из одной вершины (корня). | ||
| Строка 22: | Строка 23: | ||
Поскольку на каждую вершину приходится <tex>O(k)</tex> памяти, то использование памяти есть <tex>O(nk)</tex>. | Поскольку на каждую вершину приходится <tex>O(k)</tex> памяти, то использование памяти есть <tex>O(nk)</tex>. | ||
| + | ===Другие модификации=== | ||
Бор позволяет решать задачу поиска подстроки в строке, если построить его на множестве суффиксов исходной строки.<ref>Сжатое суффиксное дерево</ref> | Бор позволяет решать задачу поиска подстроки в строке, если построить его на множестве суффиксов исходной строки.<ref>Сжатое суффиксное дерево</ref> | ||
Версия 21:43, 6 апреля 2016
Бор (англ. trie, луч, нагруженное дерево) — структура данных для хранения набора строк, представляющая из себя подвешенное дерево с символами на рёбрах. Строки получаются прохождением из корня по рёбрам, записывая соответствующие им символы, до терминальной вершины. Размер бора линейно зависит от суммы длин всех строк, а поиск в бору занимает время, пропорциональное длине образца.
Содержание
Пример
Построение
Обозначения
Введем следующие обозначения:
- — набор строк, называемый словарем;
- .
Алгоритм
Непосредственно построение:
- Начинаем с дерева из одной вершины (корня).
- Добавляем шаблоны один за другим.
- Следуем из корня по рёбрам, отмеченным буквами из , пока возможно.
- Если заканчивается в , сохраняем идентификатор (например, ) в и отмечаем вершину как терминальную.
- Если ребра, отмеченного очередной буквой нет, то создаем новые ребра и вершины для всех оставшихся символов .
Это занимает, очевидно, времени, так как поиск буквы, по которой нужно переходить, происходит за (в вершине есть указатели на буквы).
Поскольку на каждую вершину приходится памяти, то использование памяти есть .
Другие модификации
Бор позволяет решать задачу поиска подстроки в строке, если построить его на множестве суффиксов исходной строки.[1]
Существует еще одна модификация бора, называющаяся сжатый бор, отличающаяся от бора следующим улучшением: если у некоторой вершины исходящая степень равна 1, то эту вершину, ребро, входящее в нее, и ребро, исходящее из нее, можно объединить в одно ребро с более чем одним символом.
Поиск строки в бору
| Задача: |
| Требуется найти слово в словаре. |
Начинаем в корне, идем по рёбрам, отмеченным символами , пока возможно. Если с последним символом мы приходим в вершину с сохраненным идентификатором, то — слово из словаря. Если в какой-то момент ребра, отмеченного нужным символом, не находится, то строки в словаре нет. Ясно, что это занимает времени. Таким образом, бор — это эффективный способ хранить словарь и искать в нем слова.
Использование бора в качестве ассоциативного массива
Существует множество реализаций ассоциативного массива, начиная от обычного массива (храним массив в отсортированном состоянии, при добавлении элемента, все элементы с большим значением сдвигаются) и заканчивая хеш-таблицами и деревьями поиска. Ещё одну реализацию можно сделать используя бор или сжатый бор. Начнём с очевидных минусов:
- Бор хранит строки или символы, а это значит, что у значения ключа будет ограничение на тип (строки, символы, либо числа, представленные как строки).
- Если реализовывать ассоциативный массив на обычном боре, а ключами будут являться строки, то будет использоваться слишком много памяти, а так же будет большая константа
- Если у нас все строки будут являться префиксами друг друга, то поиск и добавление могут занимать действий в худшем случае (например хранятся слова ), где - количество слов
Плюсы:
- Достаточно простая реализация.
- Операции добавления имеют меньшую константу (из-за отсутствия всевозможных операций балансировки), чем у двоичных деревьев поиска, поэтому в среднем данная реализация может работать быстрее.
- Сортировка элементов гарантируется уже самим построением бора.
См. также
Источники информации
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — ISBN 5-8489-0857-4
- Бор. Построение бора
Ссылки
- ↑ Сжатое суффиксное дерево
