Бор — различия между версиями
(→Обозначения) |
(→Алгоритм) |
||
| Строка 15: | Строка 15: | ||
===Алгоритм=== | ===Алгоритм=== | ||
Непосредственно построение: | Непосредственно построение: | ||
| − | *Начало | + | *Начало. |
| − | *'''Шаг 1.''' | + | *'''Шаг 1.''' Создадим [[Дерево, эквивалентные определения | дерево]] из одной вершины(в нашем случае корня). |
| − | *'''Шаг 2.''' Добавляем шаблоны <tex>P_i</tex> один за другим. Следуем из корня по [[Основные определения теории графов | рёбрам]], отмеченным буквами из <tex>P_i</tex>, пока возможно | + | *'''Шаг 2.''' Добавление элементов в дерево. |
| − | + | **Добавляем шаблоны <tex>P_i</tex> один за другим. Следуем из корня по [[Основные определения теории графов | рёбрам]], отмеченным буквами из <tex>P_i</tex>, пока возможно. | |
**Если <tex>P_i</tex> заканчивается в <tex>v</tex>, сохраняем идентификатор <tex>P_i</tex> (например, <tex>i</tex>) в <tex>v</tex> и отмечаем вершину <tex>v</tex> как терминальную. | **Если <tex>P_i</tex> заканчивается в <tex>v</tex>, сохраняем идентификатор <tex>P_i</tex> (например, <tex>i</tex>) в <tex>v</tex> и отмечаем вершину <tex>v</tex> как терминальную. | ||
**Если [[Основные определения теории графов | ребра]], отмеченного очередной буквой <tex>P_i</tex> нет, то создаем новые ребра и вершины для всех оставшихся символов <tex>P_i</tex>. | **Если [[Основные определения теории графов | ребра]], отмеченного очередной буквой <tex>P_i</tex> нет, то создаем новые ребра и вершины для всех оставшихся символов <tex>P_i</tex>. | ||
| − | *Конец | + | *Конец. |
Это занимает, очевидно, <tex>O(|P_1| + \ldots + |P_k|) = O(n)</tex> времени, так как поиск буквы, по которой нужно переходить, происходит за <tex>O(1)</tex>(в вершине есть указатели на буквы). | Это занимает, очевидно, <tex>O(|P_1| + \ldots + |P_k|) = O(n)</tex> времени, так как поиск буквы, по которой нужно переходить, происходит за <tex>O(1)</tex>(в вершине есть указатели на буквы). | ||
Версия 18:22, 13 апреля 2016
Бор (англ. trie, луч, нагруженное дерево) — структура данных для хранения набора строк, представляющая из себя подвешенное дерево с символами на рёбрах. Строки получаются прохождением из корня по рёбрам, записывая соответствующие им символы, до терминальной вершины. Размер бора линейно зависит от суммы длин всех строк, а поиск в бору занимает время, пропорциональное длине образца.
Содержание
Пример
Построение
Обозначения
Введем следующие обозначения:
- — набор строк, называемый словарем;
- — сумма длин строк.
Бор храним как дерево, в котором на ребрах хранятся символы, а в вершинах указатели на конец строки или её продолжение.
Алгоритм
Непосредственно построение:
- Начало.
- Шаг 1. Создадим дерево из одной вершины(в нашем случае корня).
- Шаг 2. Добавление элементов в дерево.
- Добавляем шаблоны один за другим. Следуем из корня по рёбрам, отмеченным буквами из , пока возможно.
- Если заканчивается в , сохраняем идентификатор (например, ) в и отмечаем вершину как терминальную.
- Если ребра, отмеченного очередной буквой нет, то создаем новые ребра и вершины для всех оставшихся символов .
- Конец.
Это занимает, очевидно, времени, так как поиск буквы, по которой нужно переходить, происходит за (в вершине есть указатели на буквы).
Поскольку на каждую вершину приходится памяти, то использование памяти есть .
Другие модификации
Бор позволяет решать задачу поиска подстроки в строке, если построить его на множестве суффиксов исходной строки. Такая модификация называется суффиксным бором.
Использование бора
Поиск строки в бору
| Задача: |
| Требуется найти слово в словаре. |
Начинаем в корне, идем по рёбрам, отмеченным символами , пока возможно. Если с последним символом мы приходим в вершину с сохраненным идентификатором, то — слово из словаря. Если в какой-то момент ребра, отмеченного нужным символом, не находится, то строки в словаре нет. Ясно, что это занимает времени. Таким образом, бор — это эффективный способ хранить словарь и искать в нем слова.
Использование бора в качестве ассоциативного массива
Благодаря тому, что бор позволяет решать задачу, описанную выше, он может выступать в качестве ассоциативного массива. Обычно, когда требуется такая структура, то используют двоичное дерево поиска или хеш-таблицу. Бор объединяет некоторые преимущества этих структур данных и позволяет одновременно делать следующие операции, которые каждая из структур не может делать по отдельности:
- Добавление элемента в ассоциативный массив за O(n), где n — длина строки (а дерево может за O(n log m).
- Получение всех ключей в отсортированном порядке за O(m), где m — число ключей (а хеш-таблица может только за O(m log m)).
Несмотря на данные достоинства у реализации ассоциативного массива в виде бора есть следующие недостатки:
- Бор хранит строки или символы, а это значит, что у значения ключа будет ограничение на тип (строки, символы, либо числа, представленные как строки).
- Если реализовывать ассоциативный массив на обычном боре, а ключами будут являться строки, то будет использоваться слишком много памяти, а так же будет большая константа.
См. также
Источники информации
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — ISBN 5-8489-0857-4
- Бор. Построение бора
