<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=91.185.54.128&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=91.185.54.128&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/91.185.54.128"/>
		<updated>2026-05-16T17:42:18Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%90%D1%85%D0%BE-%D0%9A%D0%BE%D1%80%D0%B0%D1%81%D0%B8%D0%BA&amp;diff=71795</id>
		<title>Алгоритм Ахо-Корасик</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%90%D1%85%D0%BE-%D0%9A%D0%BE%D1%80%D0%B0%D1%81%D0%B8%D0%BA&amp;diff=71795"/>
				<updated>2019-09-12T13:07:07Z</updated>
		
		<summary type="html">&lt;p&gt;91.185.54.128: /* Поиск шаблонов с масками */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = Дан набор строк в алфавите размера &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; суммарной длины &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;. Необходимо найти для каждой строки все ее вхождения в текст.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
=== Шаг 1. Построение бора ===&lt;br /&gt;
Строим [[Бор|бор]] из строк.&amp;lt;br /&amp;gt;&lt;br /&gt;
Построение выполняется за время &amp;lt;tex&amp;gt;O(m)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} суммарная длина строк.&lt;br /&gt;
&lt;br /&gt;
====Пример построенного бора====&lt;br /&gt;
Бор для набора строк &amp;lt;tex&amp;gt; \{ \textbf{he},\ \textbf{she},\ \textbf{his},\ \textbf{hers}\} &amp;lt;/tex&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Файл:Бор.jpg‎]]&lt;br /&gt;
&lt;br /&gt;
=== Шаг 2. Преобразование бора ===&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;[u]&amp;lt;/tex&amp;gt; слово, приводящее в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; в боре.&amp;lt;br /&amp;gt;&lt;br /&gt;
Узлы бора можно понимать как состояния [[Детерминированные_конечные_автоматы | автомата]], а корень как начальное состояние.&amp;lt;br /&amp;gt;&lt;br /&gt;
Узлы бора, в которых заканчиваются строки, становятся терминальными.&amp;lt;br /&amp;gt;&lt;br /&gt;
Для переходов по автомату заведём в узлах несколько функций:&amp;lt;br /&amp;gt;&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{parent}(u)&amp;lt;/tex&amp;gt; {{---}} возвращает родителя вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;;&amp;lt;br /&amp;gt;&lt;br /&gt;
*&amp;lt;tex&amp;gt;\pi(u) = \delta(\pi(\mathrm{parent}(u)), c)&amp;lt;/tex&amp;gt; {{---}} '''суффиксная ссылка''', и существует переход из  &amp;lt;tex&amp;gt;\mathrm{parent}(u)&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;;&amp;lt;br /&amp;gt;&lt;br /&gt;
*&amp;lt;tex&amp;gt;\delta(u, c) = &lt;br /&gt;
  \begin{cases}&lt;br /&gt;
     v,                 &amp;amp;\text{if $v$ is son by symbol $c$ in trie;}\\&lt;br /&gt;
     root,              &amp;amp;\text{if $u$ is root and $u$ has no child by symbol $c$ in trie}\\&lt;br /&gt;
     \delta(\pi(u), c), &amp;amp;\text{else.}&lt;br /&gt;
   \end{cases}&amp;lt;/tex&amp;gt; {{---}} функция перехода.&lt;br /&gt;
Мы можем понимать рёбра бора как переходы в автомате по соответствующей букве. Однако одними только рёбрами бора нельзя ограничиваться. Если мы пытаемся выполнить переход по какой-либо букве, а соответствующего ребра в боре нет, то мы тем не менее должны перейти в какое-то состояние. Для этого нам и нужны суффиксные ссылки.&lt;br /&gt;
&amp;lt;br&amp;gt; Суффиксная ссылка &amp;lt;tex&amp;gt;\pi(u) = v&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;[v]&amp;lt;/tex&amp;gt; {{---}} максимальный суффикс &amp;lt;tex&amp;gt;[u]&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;[v]\neq[u]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Функции перехода и суффиксные ссылки можно найти либо алгоритмом [[Обход в глубину, цвета вершин | обхода в глубину]] с ленивыми вычислениями, либо с помощью алгоритма [[Обход в ширину | обхода в ширину]].&lt;br /&gt;
&lt;br /&gt;
Из определений выше можно заметить два следующих факта:&lt;br /&gt;
* функция перехода определена через суффиксную ссылку, а суффиксная ссылка {{---}} через функию переходов;&lt;br /&gt;
* для построения суффиксных ссылок небходимо знать информацию только выше по бору от текущей вершины до корня.&lt;br /&gt;
Это позволяет реализовать функции поиска переходов по символу и суффиксных ссылок ленивым образом при помощи взаимной рекурсии.&lt;br /&gt;
&lt;br /&gt;
==== Пример автомата Ахо-Корасик ====&lt;br /&gt;
[[Файл:axo.jpg]]&amp;lt;br /&amp;gt;&lt;br /&gt;
Пунктиром обозначены суффиксные ссылки. Из вершин, для которых они не показаны, суффиксные ссылки идут в корень.&lt;br /&gt;
&lt;br /&gt;
Суффиксная ссылка для каждой вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; — это вершина, в которой оканчивается наидлиннейший собственный суффикс строки, соответствующей вершине &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;. Единственный особый случай — корень бора: для удобства суффиксную ссылку из него проведём в себя же. Например, для вершины &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; с соответствующей ей строкой &amp;lt;tex&amp;gt;&amp;quot;she&amp;quot;&amp;lt;/tex&amp;gt; максимальным подходящим суффиксом является строка &amp;lt;tex&amp;gt;&amp;quot;he&amp;quot;&amp;lt;/tex&amp;gt;. Видим, что такая строка заканчивается в вершине &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Следовательно суффиксной ссылкой вершины для &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; является вершина &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
===Шаг 3. Построение сжатых суффиксных ссылок ===&lt;br /&gt;
При построении автомата может возникнуть такая ситуация, что ветвление есть не на каждом символе. Тогда можно маленький бамбук заменить одним ребром. Для этого и используются сжатые суффиксные ссылки.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;up(u) = &lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    \pi(u),     &amp;amp;\text{if $\pi(u)$ is terminal;}\\&lt;br /&gt;
    \varnothing,&amp;amp;\text{if $\pi(u)$ is root;}\\&lt;br /&gt;
    up(\pi(u)), &amp;amp;\text{else.}&lt;br /&gt;
  \end{cases}&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;up&amp;lt;/tex&amp;gt; {{---}} сжатая суффиксная ссылка, т.е. ближайшее допускающее состояние (терминал) перехода по суффиксным ссылкам. Аналогично обычным суффиксным ссылкам сжатые суффиксные ссылки могут быть найдены при помощи ленивой рекурсии.&lt;br /&gt;
&lt;br /&gt;
== Использование автомата ==&lt;br /&gt;
Теперь нужно сказать немного слов о том, как мы будем использовать наш автомат. По очереди просматриваем символы текста. Для очередного символа &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; переходим из текущего состояния &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; в состояние, которое вернёт функция &amp;lt;tex&amp;gt;\delta(u, c)&amp;lt;/tex&amp;gt;. Оказавшись в новом состоянии, отмечаем по сжатым суффиксным ссылкам строки, которые нам встретились и их позицию (если требуется). Если новое состояние является терминалом, то соответствующие ему строки тоже отмечаем.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Пример реализации ==&lt;br /&gt;
Ниже представлена реализация некоторых функций (используется ленивая рекурсия).&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} размер алфавита.&lt;br /&gt;
&lt;br /&gt;
'''Структура вершины:'''&lt;br /&gt;
 '''struct''' Node:&lt;br /&gt;
     '''Node''' son[k]                                 &amp;lt;font color=green&amp;gt;// массив сыновей&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''Node''' go[k]                                  &amp;lt;font color=green&amp;gt;// массив переходов (запоминаем переходы в ленивой рекурсии), используемый для вычисления суффиксных ссылок&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''Node''' parent                                 &amp;lt;font color=green&amp;gt;// вершина родитель&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''Node''' suffLink                               &amp;lt;font color=green&amp;gt;// суффиксная ссылка (вычисляем в ленивой рекурсии)&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''Node''' up                                     &amp;lt;font color=green&amp;gt;// сжатая суффиксная ссылка&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''char''' charToParent                           &amp;lt;font color=green&amp;gt;// символ, ведущий к родителю&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''bool''' isLeaf                                 &amp;lt;font color=green&amp;gt;// флаг, является ли вершина терминалом&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''vector&amp;lt;int&amp;gt;''' leafPatternNumber               &amp;lt;font color=green&amp;gt;// номера строк, за которые отвечает терминал&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Функция для вычисления суффиксной ссылки:'''&lt;br /&gt;
 '''Node''' getSuffLink('''Node''' v):&lt;br /&gt;
     '''if''' v.suffLink == ''null''                       &amp;lt;font color=green&amp;gt;// если суффиксная ссылка ещё не вычислена&amp;lt;/font&amp;gt;&lt;br /&gt;
        '''if''' v == root '''or''' v.parent == root&lt;br /&gt;
             v.suffLink = root&lt;br /&gt;
        '''else'''&lt;br /&gt;
             v.suffLink = getLink(getSuffLink(v.parent), v.charToParent)&lt;br /&gt;
     '''return''' v.suffLink&lt;br /&gt;
 &lt;br /&gt;
'''Функция для вычисления перехода:'''&lt;br /&gt;
 '''Node''' getLink('''Node''' v, '''char''' c): &lt;br /&gt;
    '''if''' v.go[c] == ''null''                           &amp;lt;font color=green&amp;gt;// если переход по символу c ещё не вычислен&amp;lt;/font&amp;gt;&lt;br /&gt;
         '''if''' v.son[c]&lt;br /&gt;
             v.go[c] = v.son[c]&lt;br /&gt;
         '''else''' '''if''' v == root &lt;br /&gt;
             v.go[c] = root &lt;br /&gt;
         '''else''' &lt;br /&gt;
             v.go[c] = getLink(getSuffLink(v), c)&lt;br /&gt;
     '''return''' v.go[c]&lt;br /&gt;
 &lt;br /&gt;
'''Функция для вычисления сжатой суффиксной ссылки:'''&lt;br /&gt;
 '''Node''' getUp('''Node''' v):&lt;br /&gt;
     '''if''' v.up == ''null''                             &amp;lt;font color=green&amp;gt;// если сжатая суффиксная ссылка ещё не вычислена&amp;lt;/font&amp;gt;&lt;br /&gt;
         '''if''' getSuffLink(v).isLeaf&lt;br /&gt;
             v.up = getSuffLink(v)&lt;br /&gt;
         '''else''' '''if''' getSuffLink(v) == root&lt;br /&gt;
             v.up = root&lt;br /&gt;
         '''else''' &lt;br /&gt;
             v.up = getUp(getSuffLink(v))&lt;br /&gt;
     '''return''' v.up&lt;br /&gt;
&lt;br /&gt;
'''Функция для добавления строки в бор:'''&lt;br /&gt;
 '''fun''' addString('''string''' s, '''int''' patternNumber):&lt;br /&gt;
     '''Node''' cur = root&lt;br /&gt;
     '''for''' i = 0 '''to''' s.length - 1&lt;br /&gt;
         '''char''' c = s[i]&lt;br /&gt;
         '''if''' cur.son[c] == 0&lt;br /&gt;
             cur.son[c] = Node&lt;br /&gt;
             &amp;lt;font color=green&amp;gt;/* здесь также нужно обнулить указатели на переходы и сыновей */&amp;lt;/font&amp;gt;&lt;br /&gt;
             cur.son[c].suffLink = 0&lt;br /&gt;
             cur.son[c].up = 0&lt;br /&gt;
             cur.son[c].parent = cur&lt;br /&gt;
             cur.son[c].charToParent = c&lt;br /&gt;
             cur.son[c].isLeaf = ''false''&lt;br /&gt;
         cur = cur.son[c]&lt;br /&gt;
     cur.isLeaf = ''true''&lt;br /&gt;
     cur.leafPatternNumber.pushBack(patternNumber)&lt;br /&gt;
'''Функция для процессинга текста (поиск, встречается строка или нет):'''&lt;br /&gt;
 '''fun''' processText('''string''' t):   &lt;br /&gt;
     '''Node''' cur = root&lt;br /&gt;
     '''for''' i = 0 '''to''' t.length - 1 &lt;br /&gt;
         '''char''' c = t[i] - 'a'&lt;br /&gt;
         cur = getLink(cur, c)&lt;br /&gt;
         &amp;lt;font color=green&amp;gt;/* В этом месте кода должен выполняться переход по '''сжатой''' суффиксной ссылке getUp(cur). Для вершины,&lt;br /&gt;
            обнаруженной по ней тоже ставим, что она найдена, затем повторяем для её сжатой суффиксной ссылки&lt;br /&gt;
            и так до корня. */&amp;lt;/font&amp;gt;&lt;br /&gt;
Кроме этих функций требуется инициализация, но она имеет отношение только к кодированию, поэтому здесь приведена не будет.&lt;br /&gt;
&lt;br /&gt;
== Оптимизации ==&lt;br /&gt;
Существует несколько оптимизаций данного алгоритма, направленных на случаи, когда нас интересует только первое вхождение образца в текст:&lt;br /&gt;
&lt;br /&gt;
# '''Сброс сжатых суффиксных ссылок для посещённых вершин.''' &lt;br /&gt;
#: Существенно ускорить работу алгоритма могут пометки о посещённости узла, то есть если узел посещён, то не переходить по сжатым суффиксным ссылкам. Вместо хранения пометок можно просто сбрасывать сжатую суффиксную ссылку.&lt;br /&gt;
# '''Сброс пометки терминальной вершины.''' &lt;br /&gt;
#: В изначальном множестве образцов могут быть дублирующиеся строки. Мы можем хотеть из различать, если с одинаковыми строками связана разная мета-информация. Тогда при попадании в терминальную вершину можно осуществлять сброс пометки этой терминальной вершины, что сэкономит время на обновлении информации о вхождении образцов в текст. Тривиальным примером, в котором возникает ситуация долгой обработки, служит огромное множество образцов из одинаковых символов и текст только из этих символов.&lt;br /&gt;
&lt;br /&gt;
== Поиск шаблонов с масками ==&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; {{---}} маска, обозначающая любой одиночный символ. Необходимо найти для каждого заданного шаблона с масками все его вхождения в текст.&amp;lt;BR&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Например, шаблон &amp;lt;tex&amp;gt;ab\varphi\varphi c\varphi&amp;lt;/tex&amp;gt;, который содержит в себе три маски, встречается на позициях &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt; строки &amp;lt;tex&amp;gt;xabvccababcax&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
=== Алгоритм поиска ===&lt;br /&gt;
&lt;br /&gt;
Для того чтобы найти все вхождения в текст заданного шаблона с масками &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, необходимо обнаружить вхождения в текст всех его безмасочных кусков.&amp;lt;BR&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\{Q_1, \dots, Q_k \}&amp;lt;/tex&amp;gt; {{---}} набор подстрок&lt;br /&gt;
&amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, разделенных масками, и пусть &amp;lt;tex&amp;gt;\{ l_1, \dots, l_k \}&amp;lt;/tex&amp;gt; {{---}} их стартовые позиции в &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;. Например, шаблон &amp;lt;tex&amp;gt;ab\varphi\varphi c\varphi&amp;lt;/tex&amp;gt; содержит две подстроки без масок &amp;lt;tex&amp;gt;ab&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; и их стартовые позиции соответственно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt;. Для алгоритма понадобится массив &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;C[i]&amp;lt;/tex&amp;gt; {{---}} количество встретившихся в тексте безмасочных подстрок шаблона, который начинается в тексте на позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. Тогда появление подстроки &amp;lt;tex&amp;gt;Q_i&amp;lt;/tex&amp;gt; в тексте на позиции &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; будет означать возможное появление шаблона на позиции &amp;lt;tex&amp;gt;j - l_i + 1&amp;lt;/tex&amp;gt;.&amp;lt;BR&amp;gt;&lt;br /&gt;
# Используя алгоритм Ахо-Корасик, находим безмасочные подстроки шаблона &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;: когда находим &amp;lt;tex&amp;gt;Q_i&amp;lt;/tex&amp;gt; в тексте &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на позиции &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, увеличиваем на единицу &amp;lt;tex&amp;gt;C[j - l_i + 1]&amp;lt;/tex&amp;gt;.&amp;lt;BR&amp;gt;&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, для которого &amp;lt;tex&amp;gt;C[i] = k&amp;lt;/tex&amp;gt;, является стартовой позицией появления шаблона &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; в тексте.&amp;lt;BR&amp;gt;&lt;br /&gt;
Рассмотрим подстроку текста &amp;lt;tex&amp;gt;T[i \dots i+n-1]&amp;lt;/tex&amp;gt;. Равенство &amp;lt;tex&amp;gt;C[i] = k&amp;lt;/tex&amp;gt; будет означать, что подстроки текста &amp;lt;tex&amp;gt; T[i + l_1 \dots i + l_1 + |Q_1| - 1],  T[i + l_2 \dots i + l_2 + |Q_2| - 1]&amp;lt;/tex&amp;gt; и так далее будут равны соответственно безмасочным подстрокам шаблона &amp;lt;tex&amp;gt;\{Q_1, \dots , Q_k \}&amp;lt;/tex&amp;gt;. Остальная часть шаблона является масками, поэтому шаблон входит в текст на позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&amp;lt;BR&amp;gt;&lt;br /&gt;
Поиск подстрок заданного шаблона с помощью алгоритма Ахо-Корасик выполняется за время &amp;lt;tex&amp;gt;O(m+n+a)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} суммарная длина подстрок, то есть длина шаблона, &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} длина текста, &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; {{---}} количество появлений подстрок шаблона. Далее просто надо пробежаться по массиву &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и просмотреть значения ячеек за время &amp;lt;tex&amp;gt;O (m)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Алгоритм Бойера-Мура]]&lt;br /&gt;
* [[Алгоритм Кнута-Морриса-Пратта]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
*[http://e-maxx.ru/algo/aho_corasick MAXimal :: algo :: Алгоритм Ахо-Корасик]&lt;br /&gt;
*[http://aho-corasick.narod.ru Сопоставление множеств и алгоритм Ахо-Корасик]&lt;br /&gt;
*[http://codeforces.com/blog/entry/14854?locale=ru Codeforces :: Алгоритм Ахо-Корасик]&lt;br /&gt;
*[https://habrahabr.ru/post/198682/ Habr :: Алгоритм Ахо-Корасик]&lt;br /&gt;
*[https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%90%D1%85%D0%BE_%E2%80%94_%D0%9A%D0%BE%D1%80%D0%B0%D1%81%D0%B8%D0%BA Wiki :: Алгоритм Ахо-Корасик]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]] &lt;br /&gt;
[[Категория: Поиск подстроки в строке]]&lt;br /&gt;
[[Категория: Точный поиск]]&lt;/div&gt;</summary>
		<author><name>91.185.54.128</name></author>	</entry>

	</feed>