Appearance
Ахо-Корасик
Пусть дан набор строк
Построение дерева
Пусть у нас есть бор — дерево с корнем в некоторой вершине
Рассмотрим в боре любой путь из корня; выпишем подряд метки рёбер этого пути. В результате мы получим некоторую строку, которая соответствует этому пути. Если же мы рассмотрим любую вершину бора, то ей поставим в соответствие строку, соответствующую пути из корня до этой вершины.
Каждая вершина бора также имеет флаг isTerminal, который равен true, если в этой вершине оканчивается какая-либо строка из словаря.
Мы можем хранить бор в виде массива
Вначале бор состоит только из одной вершины — корня, а далее будем добавлять в него строки
Добавление в бор заданной строки
- Встаём в корень бора, смотрим, есть ли из корня переход по букве
- Если переход есть, то переходим по нему в другую вершину
- Иначе создаём новую вершину и добавляем переход в эту вершину по букве
- Затем, стоя в какой-то вершине, повторяем процесс для букв
- После окончания процесса помечаем последнюю посещённую вершину, как терминальную
Пример. Пусть у нас есть словарь

Суффиксные и автоматные ссылки
Обозначим за
Определение. Суффиксная ссылка
Определение. Автоматный переход
Построение суффиксных ссылок
Суффиксная ссылка для каждой вершины
Например, для вершины

Вычисление автоматных ссылок
Автоматные ссылки вычисляются с использованием суффиксных ссылок и обычных переходов. Алгоритм строит автоматные ссылки по следующей логике:
- Мы стоим в некоторой вершине
и хотим перейти по символу , тогда - Если есть обычный переход по символу
, то автоматная ссылка просто указывает на этот переход: v->autLink[c] = &v->next[c] - Если из вершины
нет перехода по , то автоматная ссылка переходит по суффиксной ссылке (если ее нет, то автомат идет в корень) - Смотрим, есть ли переход по символу
из вершины, в которую мы попали - Если да, то автоматная ссылка указывает на вершину, в которую мы попадем, сделав переход по
- Если нет, то снова пытаемся пройти по суффиксной ссылке, повторяя алгоритм, пока не попадем либо в корень, либо к нужному ребру
- Смотрим, есть ли переход по символу
- Если текущая вершина — корень, то автоматная ссылка замыкается на сам корень, то есть:
v->autLink[c] = v - Если это не корень, то автоматная ссылка указывает на результат перехода по суффиксной ссылке:
v->autLink[c] = v->sufLink->autLink[c]
- Если есть обычный переход по символу
Работа автоматных ссылок и зачем они нужны
Предположим, что мы находимся в вершине
Фактически, автоматная ссылка — это резервный переход в другую вершину, где мы можем продолжить поиск.
Автоматные ссылки помогают избежать возврата назад по тексту при поиске. Если символ не подошел, мы просто переходим к другой вершине, которая может соответствовать суффиксу уже обработанной части текста
После построения автоматных ссылок мы можем переходить по ним за
Сложность
Пусть у нас есть словарь
Построение бора, суффиксных ссылок и автомата займет
- В боре каждая вершина соответствует одному символу из набора строк. Значит, мы добавляем каждый символ всех строк в бор один раз
- Суффиксные ссылки для каждой вершины бора строятся с помощью BFS. Для каждой вершины мы проверяем её суффиксную ссылку, а это делается за
, так как каждая вершина обрабатывается один раз - Автоматные ссылки тоже строятся в процессе обхода бора по тому же принципу, что и суффиксные ссылки. Для каждой вершины выполняется один проход по суффиксной ссылке и проверяются символы, что снова занимает
времени (построение)