Суффиксный автомат — различия между версиями
(Новая страница: «{{Определение |definition = '''Суффиксный автомат''' (англ. ''suffix automaton'', ''directed acyclic word graph'') {{---}} мин...») |
|||
Строка 42: | Строка 42: | ||
Пусть длина самой короткой строки, которая принимается состоянием <tex>q</tex> равно <tex>k</tex>, тогда '''суффиксная ссылка''' <tex>link_q</tex> будет вести из этого состояния в состояние, которое принимает эту же строку без первого символа. | Пусть длина самой короткой строки, которая принимается состоянием <tex>q</tex> равно <tex>k</tex>, тогда '''суффиксная ссылка''' <tex>link_q</tex> будет вести из этого состояния в состояние, которое принимает эту же строку без первого символа. | ||
}} | }} | ||
− | Будем обозначать длину самой длинной строки, которая принимается состоянием <tex>q</tex> как <tex>len_q</tex>. Длина самой короткой строки из <tex>q</tex> в таком случае будет равна <tex> | + | Будем обозначать длину самой длинной строки, которая принимается состоянием <tex>q</tex> как <tex>len_q</tex>. Длина самой короткой строки из <tex>q</tex> в таком случае будет равна <tex>len(link_q) + 1</tex>. |
+ | Суффиксный автомат может быть построен за линейное время online-алгоритмом. Будем добавлять символы строки <tex>s</tex> по одному, перестраивая при этом автомат. | ||
+ | Изначально автомат состоит из одного состояния, для которого <tex>len(0) = 0</tex>, а <tex>link_0 = -1</tex>. | ||
+ | <br>Обозначим состояние <tex>last</tex>, соответствующее текущей строке до добавления символа <tex>c</tex> (изначально <tex>last = 0</tex>). <br>Создадим новое состояние <tex>cur</tex>, <tex>len(cur) = len(last) + 1</tex>. <br>Рассмотрим все переходы из <tex>last</tex> по текущему символу <tex>c</tex>. Если перехода нет, то добавляем переход в <tex>cur</tex>, переходим по суффиксной ссылке и повторяем процедуру снова. Если переход существует, то остановимся и обозначим текущее состояние за <tex>p</tex>. Если перехода не нашлось и по суффиксным ссылкам мы дошли до фиктивного состояния (на которое указывает <tex>link_0</tex>), то <tex>link_{cur} = 0</tex>.<br> | ||
+ | Допустим, что мы остановились в состоянии <tex>p</tex>, из которого существует переход с символом <tex>c</tex>. Обозначим состояние, куда ведёт переход, через <tex>q</tex>. Рассмотрим два случая:<br> | ||
+ | # Если <tex>len(p) + 1 = len(q)</tex>, то <tex>link(q) = cur</tex>.<br> | ||
+ | # В противном случае, создадим новое состояние <tex>new</tex>, скопируем в него <tex>q</tex> вместе с суффиксными ссылками и переходами. <tex>len(new)</tex> присвоим значение <tex>len(p) + 1</tex>. Перенаправим суффиксную ссылку из <tex>q</tex> в <tex>new</tex> и добавим ссылку из <tex>cur</tex> в <tex>new</tex>. Пройдём по всем суффиксным ссылкам из состояния <tex>p</tex> и все переходы в состояние <tex>q</tex> по символу <tex>c</tex> перенаправим в <tex>new</tex>. | ||
+ | Обновим значение <tex>last = cur</tex>. | ||
− | ... | + | ==Реализация== |
+ | * Переходы хранятся в массиве отображений (ключ {{---}} символ, значение {{---}} номер состояния) <tex>edges</tex>, | ||
+ | * Суффиксные ссылки хранятся в массиве <tex>link</tex>, | ||
+ | * Длины строк хранятся в массиве <tex>len</tex>. | ||
+ | |||
+ | '''func''' addChar(c)''':''' | ||
+ | r = newState() <font color="green">// создаём новое состояние и возвращаем его номер</font> | ||
+ | |||
+ | p = last | ||
+ | '''while''' p >= 0 '''and''' edges[p].find(c) == edges[p].end()''':''' | ||
+ | edges[p][c] = r | ||
+ | p = link[p] | ||
+ | |||
+ | '''if''' p != -1''':''' | ||
+ | q = edges[p][c] | ||
+ | '''if''' length[p] + 1 == length[q]''':''' | ||
+ | link[r] = q | ||
+ | '''else:''' | ||
+ | new = clone(q) <font color="green">// скопируем состояние <tex>q</tex></font> | ||
+ | link[q] = link[r] = new | ||
+ | '''while''' p >= 0 '''and''' edges[p][c] == q''':''' | ||
+ | edges[p][c] = new | ||
+ | p = link[p] | ||
+ | last = r | ||
==Источники информации== | ==Источники информации== |
Версия 17:24, 14 марта 2016
Определение: |
Суффиксный автомат (англ. suffix automaton, directed acyclic word graph) — минимальный ДКА, который принимает все суффиксы строки и только их. |
Содержание
Описание
Суффиксный автомат
для строки представляет собой ациклический ориентированный граф, с начальной вершиной и множеством терминальных вершин, рёбра которого помечены символами .
Определение: |
Состояние | принимает строку , если существует путь из начального состояния в , такой, что если последовательно выписать буквы на рёбрах на пути, получим строку .
Определение: |
Автомат принимает строку | , если её принимает хотя бы одно из финальных состояний.
Так как автомат детерминированный, то каждому пути соответствует строка.
Если две строки
и принимаются одним состоянием произвольного автомата, то для любой строки строки и принимаются или не принимаются автоматом одновременно. Действительно, независимо от того, как мы пришли в состояние , если мы пройдём из него по пути, соответствующему строке , мы сможем точно сказать, в какое состояние мы попадём (в частности, будет ли оно финальным). Значит, любому состоянию соответствует множество строк , которые переводят его в одно из конечных состояний.Определение: |
Множество | называют правым контекстом состояния.
Правый контекст определен не только для состояния, но и для строк, которые оно принимает — правый контекст строк совпадает с правым контекстом состояния.
Утверждение: |
Состояний в автомате не меньше, чем различных правых контекстов у подстрок строки, для которой он построен, причём в минимальном автомате достигается нижняя оценка. |
Допустим, что в автомате есть два состояния | и такие что . Мы можем удалить состояние и перевести переходы, ведущие в него в состояние . Множество принимаемых строк от этого не изменится, следовательно, мы можем продолжать, пока количество состояний не будет равно числу попарно различных правых контекстов.
Таким образом, ДКА является минимальным тогда и только тогда, когда правые контексты всех его состояний попарно различны. В случае суффиксного автомата правый контекст
строки взаимнооднозначно соответствует множеству правых позиций вхождений строки в строку . Таким образом, каждое состояние автомата принимает строки с одинаковым множеством правых позиций их вхождений и обратно, все строки с таким множеством позиций принимается этим состоянием.Построение
Определение: |
Пусть длина самой короткой строки, которая принимается состоянием | равно , тогда суффиксная ссылка будет вести из этого состояния в состояние, которое принимает эту же строку без первого символа.
Будем обозначать длину самой длинной строки, которая принимается состоянием
Обозначим состояние , соответствующее текущей строке до добавления символа (изначально ).
Создадим новое состояние , .
Рассмотрим все переходы из по текущему символу . Если перехода нет, то добавляем переход в , переходим по суффиксной ссылке и повторяем процедуру снова. Если переход существует, то остановимся и обозначим текущее состояние за . Если перехода не нашлось и по суффиксным ссылкам мы дошли до фиктивного состояния (на которое указывает ), то .
Допустим, что мы остановились в состоянии , из которого существует переход с символом . Обозначим состояние, куда ведёт переход, через . Рассмотрим два случая:
- Если
- В противном случае, создадим новое состояние , скопируем в него вместе с суффиксными ссылками и переходами. присвоим значение . Перенаправим суффиксную ссылку из в и добавим ссылку из в . Пройдём по всем суффиксным ссылкам из состояния и все переходы в состояние по символу перенаправим в .
Обновим значение
.Реализация
- Переходы хранятся в массиве отображений (ключ — символ, значение — номер состояния) ,
- Суффиксные ссылки хранятся в массиве ,
- Длины строк хранятся в массиве .
func addChar(c):
r = newState() // создаём новое состояние и возвращаем его номер
p = last
while p >= 0 and edges[p].find(c) == edges[p].end():
edges[p][c] = r
p = link[p]
if p != -1:
q = edges[p][c]
if length[p] + 1 == length[q]:
link[r] = q
else:
new = clone(q) // скопируем состояние
link[q] = link[r] = new
while p >= 0 and edges[p][c] == q:
edges[p][c] = new
p = link[p]
last = r
Источники информации
- Maxime Crochemore, Christophe Hancart, Thierry Lecroq — Algorithms on Strings
- А. Кульков — Лекция по суффиксным структурам