Інфо та теорія
Aho–Corasick знаходить кожне входження кількох
шаблонів у тексті за один лінійний прохід, поєднуючи
бор (trie) усіх шаблонів із
fail-посиланнями, що узагальнюють ідею,
покладену в основу однопатернового алгоритму
KMP.
1. Побудова бора
Кожен шаблон вставляється у спільний бор із коренем у
вузлі 0. Кожен вузол відповідає рядку, що
утворюється шляхом від кореня; вузол позначається як
output-вузол, якщо цей шлях збігається з одним
із шаблонів.
2. Fail-посилання (BFS)
Для кожного вузла v, до якого дістаються з
батьківського вузла u через символ
c, fail-посилання f(v)
вказує на вузол, що відповідає найдовшому власному суфіксу
рядка вузла v, який водночас є префіксом
якогось шаблону (тобто теж є вузлом бора). Fail-посилання
обчислюються за допомогою обходу BFS по бору,
рівень за рівнем: діти кореня отримують f = корінь;
для глибшого нащадка, до якого дістаються з u
через c, проходимо ланцюжком fail-посилань
вузла u, доки не знайдемо вузол із переходом
goto по c (або не повернемось до
кореня).
3. Output / словникові суфіксні посилання
Один вузол може одночасно бути суфіксом кількох
збіжних шаблонів, тож ефективна множина збігів кожного
вузла — це його власні outputs плюс усі
виходи, досяжні шляхом переходу по fail-посиланнях аж до
кореня — ланцюжок словникових суфіксів. Попереднє
обчислення цієї об'єднаної множини (або її обхід у
реальному часі) дозволяє сканеру повідомляти про кожен
шаблон, що закінчується в певній позиції, не пропускаючи
перекривних збігів.
4. Сканування
Текст подається по одному символу за раз. Із поточного стану виконується перехід по ребру бора, якщо воно існує; інакше послідовно застосовуються fail-посилання, поки не знайдеться ребро або не буде досягнуто кореня. Після кожного переходу об'єднана множина виходів нового стану повідомляється як збіги, що закінчуються в цій позиції.
Складність
Побудова бора та fail-посилань коштує
O(m), де m — сумарна довжина всіх
шаблонів; сканування тексту коштує O(n), де
n — довжина тексту. Виведення всіх збігів
коштує O(z), де z — кількість
збігів, що в сумі дає O(n + m + z).