Сжатое суффиксное дерево — различия между версиями
(→Определение) |
|||
| Строка 2: | Строка 2: | ||
==Определение== | ==Определение== | ||
| + | {{Определение | ||
| + | |definition = | ||
'''Суффиксное дерево''' (сжатое суффиксное дерево) <tex>T</tex> для строки <tex>s</tex> (где <tex>|s| = n</tex>) {{---}} дерево с <tex>n</tex> листьями, каждая внутренняя вершина которого имеет не меньше двух детей, а каждое ребро помечено непустой подстрокой строки <tex>s</tex>. Два ребра, выходящие из одной вершины, не могут иметь подстрок, начинающихся с одного и того же символа. | '''Суффиксное дерево''' (сжатое суффиксное дерево) <tex>T</tex> для строки <tex>s</tex> (где <tex>|s| = n</tex>) {{---}} дерево с <tex>n</tex> листьями, каждая внутренняя вершина которого имеет не меньше двух детей, а каждое ребро помечено непустой подстрокой строки <tex>s</tex>. Два ребра, выходящие из одной вершины, не могут иметь подстрок, начинающихся с одного и того же символа. | ||
| − | + | }} | |
| − | + | Сжатое суффиксное дерево, как и бор, содержит все суффиксы строки <tex>s</tex>, причем каждый суффикс заканчивается точно в листе и нигде кроме него. [[Файл:Suffix_tree_3.png|thumb|right|Суффиксное дерево для строки <tex>xabxa</tex> с защитным символом]] | |
| − | [[Файл:Suffix_tree_3.png|thumb|right|Суффиксное дерево для строки <tex>xabxa</tex> с защитным символом]] | + | Рассмотрим дерево для строки <tex>xabxa</tex>. У него суффикс <tex>xa</tex> является префиксом суффикса <tex>xabxa</tex>, значит, этот суффикс не закачивается в листе. Для решения проблемы в конце строки <tex>s</tex> добавляют символ, не входящий в исходный алфавит: '''''защитный''''' символ. Как правило, это <tex>\$</tex>. Любой суффикс строки с защитным символом действительно заканчивается в листе и только в листе. |
| − | |||
Далее <tex>n</tex> - длина строки <tex>s</tex> с защитным символом. | Далее <tex>n</tex> - длина строки <tex>s</tex> с защитным символом. | ||
Версия 14:02, 1 июня 2012
Суффиксный бор — удобная структура данных для поиска подстроки в строке, но она занимает много места в памяти. Рассмотрим в боре все пути от до , в которых у каждой вершины только один сын. Такой путь можно сжать до ребра , записав на нем все встречающиеся на пути символы, которые являются подстрокой исходной строки. Для хранения ее на ребре обычно используют индексы начала и конца. Получилось сжатое суффиксное дерево.
Содержание
Определение
| Определение: |
| Суффиксное дерево (сжатое суффиксное дерево) для строки (где ) — дерево с листьями, каждая внутренняя вершина которого имеет не меньше двух детей, а каждое ребро помечено непустой подстрокой строки . Два ребра, выходящие из одной вершины, не могут иметь подстрок, начинающихся с одного и того же символа. |
Рассмотрим дерево для строки . У него суффикс является префиксом суффикса , значит, этот суффикс не закачивается в листе. Для решения проблемы в конце строки добавляют символ, не входящий в исходный алфавит: защитный символ. Как правило, это . Любой суффикс строки с защитным символом действительно заканчивается в листе и только в листе.
Далее - длина строки с защитным символом.
Количество вершин
По определению, в суффиксном дереве содержится листьев. Рассмотрим количество внутренних вершин такого дерева.
| Лемма: |
Количество внутренних вершин дерева, каждая из которых имеет не менее двух детей, меньше количества листьев. |
| Доказательство: |
|
Докажем лемму индукцией по количеству листьев . База При в дереве одна внутренняя вершина - верно. Переход Возьмем вершину в дереве с листами, у которой два ребенка - листья. Рассмотрим возможные случаи: 1) У нее более двух детей. Тогда отрежем от нее лист. Получим дерево с листьями, причем в нем количество внутренних вершин такое же, как в исходном дереве. Но у полученного дерева по индукционному предположению менее внутренних вершин, значит, для исходного дерева лемма верна. 2) У нее ровно два ребенка. Отрежем их, получим дерево с листьями, количество внутренних вершин которого на меньше, чем в исходном дереве. Тогда по индукционному предположению у него менее внутренних вершин, значит, в исходном дереве их меньше . |
Занимаемая память
Представим дерево как массив , где — количество вершин в дереве, - мощность алфавита. Для любого суффиксного дерева верна предыдущая лемма (у каждой вершины по определению не менее двух детей), значит, . Каждая ячейка содержит информацию о том, в какую вершину ведет ое ребро по ому символу и индексы . Итак, дерево занимает памяти.
Построение суффиксного дерева
Рассмотрим наивный алгоритм построения суффиксного дерева:
for to do //для каждого символа строки insert() //добавляем суффикс, начинающийся с него
insert(l,r)
while ()
if //если мы не можем пойти из вершины по символу
create_vertex() //создаем новую вершину
else
for to //для каждого символа на ребре из текущей вершины
if //если нашли не совпадающий символ
разбить ребро
break
if ребро не разбивали
//переходим по ребру
//двигаемся по суффиксу на длину подстроки, записанной на ребре
Этот алгоритм работает за время , однако алгоритм Укконена позволяет построить сжатое суффиксное дерево за .
Использование сжатого суффиксного дерева
Суффиксное дерево позволяет за линейное время найти:
- Количество различных подстрок данной строки
- Наибольшую общую подстроку двух строк
- Суффиксный массив и массив (longest common prefix) исходной строки
Источники
- Дэн Гасфилд — Строки, деревья и последовательности в алгоритмах: Информатика и вычислительная биология — СПб.: Невский Диалект; БХВ-Петербург, 2003. — 654 с: ил.