Введение
Поиск шаблонов в строках. В информатике алгоритмы поиска строк, иногда называемые алгоритмами сопоставления строк, представляют собой важный класс строковых алгоритмов, которые пытаются найти место, где одна или несколько строк (также называемых шаблонами) встречаются в более длинной строке или тексте. Простым примером поиска строк является случай, когда шаблон и искомый текст представлены массивами элементов алфавита (конечного множества) Σ. Σ может быть алфавитом человеческого языка, например, буквы от A до Z, а в других приложениях может использоваться двоичный алфавит (Σ = {0,1}) или алфавит ДНК (Σ = {A,C,G,T}) в биоинформатике. На практике эффективность алгоритма поиска строк может зависеть от кодировки строк. В частности, при использовании кодировки переменной ширины поиск N-го символа может быть замедлен и потребовать времени, пропорционального N. Это может существенно замедлить некоторые алгоритмы поиска. Одним из возможных решений является поиск последовательности кодовых единиц, однако это может привести к ложным совпадениям, если кодировка специально не разработана для их предотвращения.
In computer science, string searching algorithms, sometimes called string matching algorithms, are an important class of string algorithms that try to find a place where one or several strings (also called patterns) are found within a larger string or text. A basic example of string searching is when the pattern and the searched text are arrays of elements of an alphabet (finite set) Σ. Σ may be a human language alphabet, for example, the letters A through Z and other applications may use a binary alphabet (Σ = {0,1}) or a DNA alphabet (Σ = {A,C,G,T}) in bioinformatics. In practice, the method of feasible string search algorithm may be affected by the string encoding. In particular, if a variable width encoding is in use, then it may be slower to find the Nth character, perhaps requiring time proportional to N. This may significantly slow some search algorithms. One of many possible solutions is to search for the sequence of code units instead, but doing so may produce false matches unless the encoding is specifically designed to avoid it.
Наивный поиск строки
Простой и неэффективный способ определить, где одна строка встречается внутри другой, — это проверять каждый индекс по очереди. Сначала мы проверяем, есть ли копия "иглы", начинающаяся с первого символа "стога сена"; если нет, то проверяем, есть ли копия "иглы", начинающаяся со второго символа "стога сена", и так далее. В обычном случае, для каждого неверного положения достаточно проверить один или два символа, чтобы убедиться в его неверности, поэтому в среднем это занимает O(n + m) шагов, где n — длина "стога сена", а m — длина "иглы"; но в худшем случае, например, при поиске строки "aaaab" в строке "aaaaaaaaab", это занимает O(nm).
Поиск на основе конечного состояния автомата
При этом подходе отслеживание назад (backtracking) избегается путем построения детерминированного конечного автомата (DFA), распознающего сохраненную строку поиска. Построение таких автоматов ресурсоемко — они обычно создаются с использованием построения по подмножествам (powerset construction), — но их использование очень быстро. Например, DFA, изображенный справа, распознает слово "MOMMY". На практике этот подход часто обобщается для поиска по произвольным регулярным выражениям.
Ковры
Алгоритм Кнута — Морриса — Пратта вычисляет ДКА, распознающего входные данные, имеющие искомую строку в качестве суффикса, алгоритм Бойера — Мура начинает поиск с конца образца, поэтому обычно может перескакивать на длину всего образца на каждом шаге. Алгоритм Баэзы — Ятеса отслеживает, являлись ли предыдущие j символов префиксом искомой строки, и поэтому может быть адаптирован для нечёткого поиска строк. Алгоритм битапа является реализацией подхода Баэзы — Ятеса.
Индексные методы
Быстрые алгоритмы поиска предварительно обрабатывают текст. После построения индекса подстрок, например, суффиксного дерева или суффиксного массива, вхождения шаблона можно найти быстро. Например, суффиксное дерево можно построить за время , а все вхождения шаблона можно найти за время , при условии, что алфавит имеет постоянный размер и все внутренние узлы суффиксного дерева знают, какие листья находятся под ними. Последнего можно достичь, выполнив алгоритм DFS из корня суффиксного дерева.
Другие варианты
Некоторые методы поиска, например, поиск триграмм, предназначены для определения степени "сходства" между поисковым запросом и текстом, а не просто для установления "совпадения" или "отсутствия совпадения". Такие поиски иногда называют "приблизительными".
Классификация по ряду моделей
Различные алгоритмы можно классифицировать по числу шаблонов, которые они используют.