Изменения

Перейти к: навигация, поиск

Бор

962 байта добавлено, 19:17, 4 сентября 2022
м
rollbackEdits.php mass rollback
'''Бор''' (англ. ''trie'', ''луч'', ''нагруженное дерево'') {{---}} структура данных для хранения набора строк, представляющая из себя [[Дерево, эквивалентные определения | подвешенное дерево]] с символами на [[Основные определения теории графов | рёбрах]]. Строки получаются прохождением из корня по последовательной записью всех символов, хранящихся на [[Основные определения теории графов | рёбрамрёбрах]], записывая соответствующие им символы, до между корнем бора и терминальной вершинывершиной. Размер бора линейно
зависит от суммы длин всех строк, а поиск в бору занимает время, пропорциональное длине образца.
===Обозначения===
Введем следующие обозначения:
*<tex>\Sigma</tex> {{---}} используемый алфавит;*<tex>P = \{P_1,\ldots,P_k\} </tex> {{---}} набор строкнад <tex>\Sigma</tex>, называемый словаремсловарём;*<tex>n = \sum_{i=1}^{k|P_i|}\limits |P_i|</tex> {{---}} сумма длин строк. Бор храним как деревонабор вершин, в котором на ребрах хранятся символыу каждой из которых есть метка, обозначающая, а в вершинах является ли вершина терминальной и указатели (рёбра) на конец строки другие вершины или её продолжениена ''NULL''.   '''struct''' vertex: '''vertex''' next[<tex>| \Sigma |</tex>] '''bool''' isTerminal
===Алгоритм===
Непосредственно построение:
*Начало.
*'''Шаг 1.''' Создадим [[Дерево, эквивалентные определения | дерево]] из одной вершины(в нашем случае корня).
*'''Шаг 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>P_i</tex>.
*Конец.
Это Построение занимает, очевидно, <tex>O(|P_1| + \ldots + |P_k|) = O(n)</tex> времени, так как поиск буквы, по которой нужно переходить, происходит за <tex>O(1)</tex>(в вершине есть указатели на буквы).
Поскольку на каждую вершину приходится <tex>O(k| \Sigma |)</tex> памяти, то использование памяти есть <tex>O(nkn| \Sigma |)</tex>.
===Другие модификацииСуффиксный бор==={{main|Суффиксный бор}}Бор позволяет решать задачу [[Наивный алгоритм поиска подстроки в строке | поиска подстроки в строке]], если построить его на множестве суффиксов исходной строки. Такая модификация называется [[Суффиксный  ===Цифровой бор ==={{main| суффиксным бором]].Сверхбыстрый цифровой бор}}
==Использование бора==
{{Задача
|definition =
Требуется найти слово <tex>S</tex> в словаре.
}}
Начинаем в корнеПри решении этой задачи, идем обход бора совершается из его корня по [[Основные определения теории графов | рёбрам]], отмеченным символами строки <tex>S</tex>, пока возможно.Если с последним символом <tex>S</tex> мы приходим в терминальную вершину с сохраненным идентификатором, то <tex>S</tex> — слово из словаря.
Если в какой-то момент [[Основные определения теории графов | ребра]], отмеченного нужным символом, не находится, то строки <tex>S</tex> в словаре нет.
Ясно, что это занимает <tex>O (|S|)</tex> времени. Таким образом, бор — это эффективный способ хранить словарь и искать в нем слова.
===Использование бора в качестве ассоциативного массива===
Благодаря тому, что бор позволяет решать задачу, описанную выше, он может выступать в качестве ассоциативного массива. Обычно, когда требуется такая структура, то используют [[Дерево поиска, наивная реализация | двоичное дерево поиска]] или [[Хеш-таблица | хеш-таблицу]]. ====ОбозначенияДостоинства====*<tex>k</tex> {{---}} длина строки*<tex>m</tex> {{---}} число ключейБор объединяет некоторые преимущества этих структур данных и позволяет одновременно делать следующие операции, которые каждая из структур не может делать по отдельности.
{| class="wikitable" style="width:10cm" border==Использование====1|+Благодаря тому, что бор позволяет решать задачу, описанную выше, он может выступать в качестве ассоциативного массива. Обычно, когда требуется такая структура, то используют [[| || '''Бор''' || '''Дерево поиска, наивная реализация ''' | двоичное дерево поиска]] или [[| '''Хеш-таблица '''| хеш-таблицу]]. Бор объединяет некоторые преимущества этих структур данных и позволяет одновременно делать следующие операции, которые каждая из структур не может делать по отдельности.|-align="center" bgcolor=#FFFFFF| ''Добавление элемента в ассоциативный массив за '' | align="center" style="background: #ddffdd;" | <tex>O(k|S|)</tex> (а дерево может за | align="center" style="background: #ffdddd;" |<tex>O(|S|\log k~log~m)</tex>| align="center" style="background: #ddffdd;" | <tex>O(|S|).</tex>|-align="center" bgcolor=#FFFFFF| ''Получение всех ключей в отсортированном порядке за '' | align="center" style="background: #ddffdd;" | <tex>O(mk)</tex> | align="center" style="background: #ddffdd;" | <tex>O(а хеш-таблица может только за k)</tex> | align="center" style="background: #ffdddd;" | <tex>O(m~k\log~mk)</tex>).|} ====Недостатки====
Несмотря на данные достоинства у реализации ассоциативного массива в виде бора есть следующие недостатки:
# Бор хранит строки или символы, а это значит, что у значения ключа будет ограничение на тип (строки, символы, либо числа, представленные как строки). Чтобы это исправить, научимся приводить любой тип данных к строке. Тогда сможем хранить любой вид данных в качестве ключа.# Если реализовывать ассоциативный массив на обычном боре, а ключами будут являться строки, то будет использоваться слишком много памяти(возможен, например, вариант, когда у слов нет пересечений по префиксу, а так же тогда бор будет большая константаиспользовать <tex>O(n| \Sigma |)</tex> памяти).
==См. также==
* [[Сжатое суффиксное дерево]]
* [[Алгоритм Ахо-Корасик]]
 
== Источники информации ==
1632
правки

Навигация