Сжатое суффиксное дерево
Суффиксный бор — удобная структура для поиска подстроки в строке, но занимающая много места в памяти. Рассмотрим все такие пути от до в суффиксном боре, в которых каждая вершина имеет только одного сына. Такие пути можно сжать до одного ребра , пометив его всеми встречающимися на пути символами. Получившееся дерево носит название сжатое суффиксное дерево.
Содержание
Определение
Суффиксное дерево (сжатое суффиксное дерево) для строки (где ) — ориентированное дерево, с ровно листами, каждая внутренняя вершина которого, отличная от корня, имеет не меньше двух детей, а каждое ребро помечено непустой подстрокой строки и символом, с которого начинается эта подстрока. Никакие два ребра, выходящие из одной и той же вершины, не могут иметь одинаковых символьных пометок. Суффиксное дерево содержит все суффиксы строки : для каждого листа конкатенация подстрок на ребрах пути от корня к листу в точности составляет суффикс, который начинается в позиции , то есть .
Существование сжатого суффиксного дерева
Определение суффиксного дерева не гарантирует, что такое дерево существует для любой строки . Если один суффикс совпадает с префиксом другого суффикса, то построить суффиксное дерево, удовлетворяющее данному выше определению, невозможно, поскольку путь для первого суффикса не сможет закончиться в листе. Например, для строки суффикс является префиксом суффикса . Во избежание этого в конце строки добавляется символ, не входящий в исходный алфавит. Такой символ называется защитным. Как правило, защитный символ обозначается . Любой суффикс строки с защитным символом заканчивается в листе, т.к. этот символ не встречается в строке нигде, кроме позиции последнего символа.
Хранение суффиксного дерева
Как уже было отмечено выше, каждое ребро дерева помечается подстрокой исходной строки . Значит, можно для каждого ребра хранить не саму подстроку, а индексы начала и конца подстроки в исходной строке — . Итак, с каждым ребром дерева ассоциируются две инцидентные ей вершины, символ, с которого начинается подстрока на ребре и два числа . Представим его как массив , где — количество вершин в дереве. Каждая ячейка массива содержит информацию о том, в какую вершину ведет ребро по символу, в какую вершину оно ведет и индексы подстроки на ребре.
Количество вершин
В сжатом суффиксном дереве содержится листьев, т.к. каждый суффикс строки заканчивается в листе. Рассмотрим теперь количество внутренних вершин такого дерева.
| Лемма: |
Количество внутренних вершин дерева, каждая из которых имеет не менее двух детей, меньше количества листьев. |
| Доказательство: |
|
Докажем лемму индукцией по количеству листьев . База При в дереве одна внутренняя вершина - верно. Переход Рассмотрим все вершины в дереве для строки длины , у которых хотя бы один из детей - лист. Если среди них есть вершина, у которой более двух детей, отрежем от нее лист. Получим дерево с листьями, удовлетворяющее условию леммы по индукционному предположению, причем в нем количество внутренних вершин равно количеству внутренних вершин в исходном дереве. Тогда у полученного дерева менее внутренних вершин, значит в исходном дереве количество внутренних вершин так же меньше количества листьев. Иначе среди этих вершин есть вершина, у которой оба ребенка - листья. Отрежем оба этих листа, получим дерево с листьями, удовлетворяющее условию леммы, количество внутренних вершин которого на меньше количества внутренних вершин в исходном дереве. Тогда, по индукционному предположению, у полученного дерева менее внутренних вершин, значит в исходном дереве количество внутренних вершин меньше . |
Занимаемая память
Очевидно, суффиксное дерево в виде массива занимает памяти. Так как любое суффиксное дерево удовлетворяет условиям леммы, то количество внутренних вершин в нем меньше количества листьев, равного , поэтому для его хранения требуется памяти.
Построение суффиксного дерева
Рассмотрим наивный алгоритм построения суффиксного дерева.
Этот алгоритм работает за время, однако существует алгоритм Укконена, позволяющий построить дерево за время.
Использование
Суффиксное дерево позволяет за линейное время найти:
- Количество различных подстрок данной строки
- Наибольшую общую подстроку двух строк
- Суффиксный массив и массив (longest common prefix) исходной строки
Источники
Дэн Гасфилд — Строки, деревья и последовательности в алгоритмах: Информатика и вычислительная биология — СПб.: Невский Диалект; БХВ-Петербург, 2003. — 654 с: ил.