Поиск подстроки в строке
Версия от 16:29, 9 июня 2015; 194.85.161.36 (обсуждение) (→Классификация алгоритмов поиска подстроки в строке)
Поиск подстроки в строке (англ. String searching algorithm) — класс алгоритмов над строками, которые позволяют найти паттерн (needle) в тексте (haystack).
Содержание
Классификация алгоритмов поиска подстроки в строке
Сравнение — «чёрный ящик»
Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста.
Преимущества:
- позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо.
 
Недостатки:
- не выдается точка, в которой произошло несовпадение.
 
По порядку сравнения паттерна в тексте
Прямой
Преимущества:
- отсутствие регрессии на «плохих» данных.
 
Недостатки:
- не самая хорошая средняя асимптотическая сложность.
 
Обратный
Паттерн движется по тексту слева направо, но сравнение подстрок происходит справа налево.
Преимущества:
- при несовпадении позволяет перемещать паттерн по строке сразу на несколько символов.
 
Недостатки:
- производительность сильно зависит от данных.
 
Сравнение в необычном порядке
Специфические алгоритмы, основанные, как правило, на некоторых эмпирических наблюдениях над словарём.[1]
По количеству поисковых шаблонов
Сколько поисковых шаблонов может обработать алгоритм за один раз.
- один шаблон (англ. single pattern algorithms)
 - конечное количество шаблонов (англ. finite set of patterns)
 - бесконечное количество шаблонов (англ. infinite number of patterns) (см. Теория формальных языков)
 
По необходимости препроцессинга текста
Виды препроцессинга:
Алгоритмы, использующие препроцессинг — одни из самых быстрых в этом классе.
Сравнение алгоритмов
-  — размер алфавита
 - — длина текста
 - — длина паттерна
 - — размер ответа(кол-во пар)
 - — суммарная длина всех паттернов
 
| Название | Среднее | Худшее | Препроцессинг | Дополнительная память | Кол-во поисковых шаблонов | Порядок сравнения | Описание | 
|---|---|---|---|---|---|---|---|
|  Наивный алгоритм  (Brute Force algorithm)  | 
Single | Прямой | Сравнение — «чёрный ящик». Если достаточно мало по сравнению с , то асимптотика будет близкой к , что позволяет использовать его на практике в случаях, когда паттерн много меньше текста (например, ctrl+F в браузерах) | ||||
| Поиск подстроки в строке с помощью Z-функции | Single | Прямой | |||||
|  Алгоритм Рабина-Карпа  (Karp-Rabin algorithm)  | 
Single / Finite | Прямой | Данный алгоритм использует хэширование, что снижает скорость в среднем. Можно модифицировать для поиска нескольких паттернов | ||||
|  Алгоритм Кнута-Морриса-Пратта  (Knuth-Morris-Pratt algorith)  | 
Single | Прямой | Использует префикс-функцию | ||||
|  Алгоритм Колусси  (Colussi algorithm)  | 
Single | Прямой / Обратный | Оптимизация Алгоритма Кнута-Морриса-Пратта использует как прямой, так и обратный обход | ||||
|  Алгоритм Ахо-Корасик  (Aho–Corasick string matching algorithm)  | 
Finite | Прямой | Строит конечный автомат. Можно хранить таблицу переходов как индексный массив (array), а можно как Красно-черное дерево. В последнем случае уменьшится расход памяти, но ухудшится асимптотика | ||||
| Алгоритм Shift-Or |   — размер машинного слова  | 
Single | Прямой | Использует тот факт, что в современных процессорах битовые сдвиг и или являются атомарными. Эффективен, если . Иначе деградирует и по памяти, и по сложности | |||
|  Алгоритм Бойера-Мура  (Boyer-Moore algorithm)  | 
Single | Обратный | Считается наиболее быстрым из алгоритмов общего назначения. Использует эвристики. Существует большое количество оптимизаций[2] | ||||
|  Поиск подстроки в строке с помощью суффиксного массива  (Suffix array)  | 
Single | Прямой | Использует Суффиксный массив. Если использовать Largest common prefix (lcp), то можно уменьшить асимптотику до . Суффиксный массив можно строить стандартными способами или алгоритмом Каркайнена-Сандерса. Асимптотика приведена для построения суффиксного массива с помощью алгоритма Каркайнена-Сандерса | ||||
|  Поиск подстроки в строке с помощью суффиксного дерева  (Suffix tree)  | 
Single | Прямой | Позволяет выполнять поиск подстроки в строке за линейное время | 
Примечания
- ↑ Например, Алгоритм Райты (англ.)
 - ↑ Например, Турбо-алгоритм Бойера-Мура 
(Turbo-BM algorithm) 
Источники информации
- Википедия — Поиск подстроки
 - Википедия — String searching algorithm
 - ESMAJ — (англ.) Большое количество разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны.