Введение

Поиск шаблонов в строках. В информатике алгоритмы поиска строк, иногда называемые алгоритмами сопоставления строк, представляют собой важный класс строковых алгоритмов, которые пытаются найти место, где одна или несколько строк (также называемых шаблонами) встречаются в более длинной строке или тексте. Простым примером поиска строк является случай, когда шаблон и искомый текст представлены массивами элементов алфавита (конечного множества) Σ. Σ может быть алфавитом человеческого языка, например, буквы от A до Z, а в других приложениях может использоваться двоичный алфавит (Σ = {0,1}) или алфавит ДНК (Σ = {A,C,G,T}) в биоинформатике. На практике эффективность алгоритма поиска строк может зависеть от кодировки строк. В частности, при использовании кодировки переменной ширины поиск N-го символа может быть замедлен и потребовать времени, пропорционального N. Это может существенно замедлить некоторые алгоритмы поиска. Одним из возможных решений является поиск последовательности кодовых единиц, однако это может привести к ложным совпадениям, если кодировка специально не разработана для их предотвращения.

Наивный поиск строки

Простой и неэффективный способ определить, где одна строка встречается внутри другой, — это проверять каждый индекс по очереди. Сначала мы проверяем, есть ли копия "иглы", начинающаяся с первого символа "стога сена"; если нет, то проверяем, есть ли копия "иглы", начинающаяся со второго символа "стога сена", и так далее. В обычном случае, для каждого неверного положения достаточно проверить один или два символа, чтобы убедиться в его неверности, поэтому в среднем это занимает O(n + m) шагов, где n — длина "стога сена", а m — длина "иглы"; но в худшем случае, например, при поиске строки "aaaab" в строке "aaaaaaaaab", это занимает O(nm).

Поиск на основе конечного состояния автомата

При этом подходе отслеживание назад (backtracking) избегается путем построения детерминированного конечного автомата (DFA), распознающего сохраненную строку поиска. Построение таких автоматов ресурсоемко — они обычно создаются с использованием построения по подмножествам (powerset construction), — но их использование очень быстро. Например, DFA, изображенный справа, распознает слово "MOMMY". На практике этот подход часто обобщается для поиска по произвольным регулярным выражениям.

Ковры

Алгоритм Кнута — Морриса — Пратта вычисляет ДКА, распознающего входные данные, имеющие искомую строку в качестве суффикса, алгоритм Бойера — Мура начинает поиск с конца образца, поэтому обычно может перескакивать на длину всего образца на каждом шаге. Алгоритм Баэзы — Ятеса отслеживает, являлись ли предыдущие j символов префиксом искомой строки, и поэтому может быть адаптирован для нечёткого поиска строк. Алгоритм битапа является реализацией подхода Баэзы — Ятеса.

Индексные методы

Быстрые алгоритмы поиска предварительно обрабатывают текст. После построения индекса подстрок, например, суффиксного дерева или суффиксного массива, вхождения шаблона можно найти быстро. Например, суффиксное дерево можно построить за время , а все вхождения шаблона можно найти за время , при условии, что алфавит имеет постоянный размер и все внутренние узлы суффиксного дерева знают, какие листья находятся под ними. Последнего можно достичь, выполнив алгоритм DFS из корня суффиксного дерева.

Другие варианты

Некоторые методы поиска, например, поиск триграмм, предназначены для определения степени "сходства" между поисковым запросом и текстом, а не просто для установления "совпадения" или "отсутствия совпадения". Такие поиски иногда называют "приблизительными".

Классификация по ряду моделей

Различные алгоритмы можно классифицировать по числу шаблонов, которые они используют.