Суффиксное дерево
![]() |
Эту статью следует викифицировать. Пожалуйста, оформите её согласно общим правилам и указаниям. |
Суффиксное дерево — способ организации данных (строк), позволяющий выяснять, входит ли строка w в строку t, за время O(|w|), где w — длина строки w.
Основные определения и описание структурыПравить
Префикс w строки t — строка такая, что wv = t для некоторой
(возможно, пустой) строки v. Префикс называется собственным, если |v|
Суффикс w строки t — строка такая, что vw = t для некоторой (возможно, пустой) строки v.
Суффикс называется собственным, если |v|
Подстрока w строки t называется правым ветвлением, если t может быть представлена как uwxv и
Пусть k — узел
Т.к. каждая ветвь уникальна, если path(t) = w, мы можем обозначить узел t за
Слова, которые представлены в
Если строка w входит в words(T), w = uv,
Атомарное
Суффиксное дерево для строки t — это
Обратное префиксное дерево строки t — это суффиксное дерево для строки
Вложенный суффикс — суффикс, который входит в строку t где-нибудь ещё, наидлиннейший вложенный суффикс называется активным суффиксом строки t.
Свойства суффиксных деревьевПравить
Лемма. Местоположение w явно в компактном суффиксном дереве тогда и только тогда, когда w не является вложенным суффиксом t или w — правое ветвление.
Доказательство.
Если
Если
Теперь легко видеть, почему ответ на вопрос, входит ли слово w в строку t, может быть найден за время O(|w|): нужно только проверить, является ли w местоположением (явным или неявным) в cst(t).
Метки рёбер должны представлять собой указатели на положение в строке, чтобы суффиксное дерево расходовало память размером O(n). Метка (p,q) ребра означает подстроку
Укконен вводит название открытые рёбра для рёбер, заканчивающихся в листьях. Пометки открытых рёбер записывают как (p,
Пусть T —
Утверждение.
В ast(t) и cst(t$), где $
Доказательство.
Символ $ называется символом-стражем. Первая часть (для ast(t)) следует из определения, т.к. местоположения являются явными. Для доказательства второй (случай cst(t)) части мы должны показать, что для каждого узла
Как следует из этого доказательства, символ-страж гарантирует существование листьев для всех суффиксов. С таким символом не может быть вложенных суффиксов, кроме пустого. Если мы опустим символ-страж, некоторые суффиксы могут стать вложенными, и их местоположения станут неявными.
Требования суффиксного дерева к памятиПравить
Утверждение. Компактное суффиксное дерево может быть представлено в виде, требующем O(n) памяти.
Доказательство. Суффиксное дерево содержит не более одного листа на каждый суффикс (в точности один с символом-стражем). Каждый внутренний узел должен быть узлом ветвления, следовательно, внутренний узел имеет по меньшей мере двух потомков. Каждое ветвление увеличивает число листьев по меньшей мере на единицу, поэтому мы имеем не более n внутренних узлов и не более n листьев.
Для представления строк, являющихся метками рёбер, мы используем индексацию в исходной строке, как описано выше. Каждый узел имеет не более одного предка и, таким образом, общее число ребер не превышает 2n.
Аналогично, каждый узел имеет не более одного суффиксного звена, тогда общее число суффиксных звеньев также ограничено числом 2n. Утверждение доказано.
Как пример суффиксного дерева с 2n-1 вершинами можно рассмотреть дерево для слова
Построение дерева за линейное время. Алгоритм «MCC». («McCreight's Algorithm»)Править
Алгоритм «mсс» начинает работу с пустого дерева и добавляет суффиксы начиная с самого длинного. Алгоритм «mcc» не является алгоритмом «реального времени», т.е. для его работы необходима вся строка целиком. Для корректной работы требуется, чтобы строка завершалась специальным символом, отличным от других, так, чтобы ни один суффикс не являлся префиксом другого суффикса. Каждому суффиксу в дереве будет соответствовать лист.
Для алгоритма мы определим
Ключевой идеей алгоритма «mcc» является соотношение между
Лемма.
Если
Доказательство.
Пусть
Мы знаем местоположение
Алгоритм состоит из трех частей.
1. Сначала он определяет структуру предыдущей головы, находит следующее доступное суффиксное звено и следует по нему.
2. Затем он повторно сканирует часть предыдущей головы, для которой длина является известной (эта часть названа
3. Наконец алгоритм устанавливает суффиксное звено для
Узел ветвления создается во второй фазе повторного сканирования, если не существует местоположения
- Алгоритм 1
- Вход: строка t
- 1: T: = пустое дерево;
- 2: голова0 :=
; - 3: n:= ДЛИНА(t);
- 4: ОТ i:= 1 ДО n ВЫП
- 5: найти
, , такие, что- а. головаi-1 =
, - б. если предок узла головаi-1 не корень, обозначим его
, в противном случае - в.
и ( |головаi-1| = 0)
- а. головаi-1 =
- 6: ЕСЛИ (
>0) ТО- 7: следовать по суффиксному звену от узла
до ;
- 7: следовать по суффиксному звену от узла
- 8: КОН;
- 9:
:= Перескан( ); - 10: установить суффиксное звено от
до - 11: (
,хвостi) := Скан( ,суфi- ); - 12: добавить лист, соответствующий хвостi
- 5: найти
- 13: КОН
Обратите внимание, что если
Процедура Перескан ищет местоположение
Процедура Скан производит поиск в глубину дерева и возвращает позицию.
- Процедура 1 Перескан(n,
) - Вход: узел n', строка
- 1: i:=1;
- 2: ПОКА i
| |ВЫП- 3: найти ребро e=n
n',w1 = 1; - 4: ЕСЛИ i+|w|>|
|+1 ТО- 5: k:=|
|-i+1; - 6: расщепить ребро e с новым узлом m и ребрами n
m и m n'; - 7: ВОЗВРАТ m
- 5: k:=|
- 8: КОН;
- 9: i:=i+|w|;
- 10: n:=n'
- 3: найти ребро e=n
- 11: КОН;
- 12: ВОЗВРАТ n'
- Процедура 2 Скан(n,
) - Вход: узел n', строка
- 1: i:=1;
- 2: ПОКА существует ребро e=n
n', w1 = i ВЫП- 3: k:=1;
- 4: ПОКА wk =
i и k |w| ВЫП- 5: k:=k+1;
- 6: i:=i+1;
- 7: КОН
- 8: ЕСЛИ k>|w| ТО
- 9: n:=n';
- 10: ИНАЧЕ
- 11: расщепить ребро e с новым узлом m и ребрами n
m и m n'; - 12: ВОЗВРАТ (m,
i,..., )
- 11: расщепить ребро e с новым узлом m и ребрами n
- 13: КОН
- 14: КОН
- 15: ВОЗВРАТ (n,
i,..., )