Поиск подстроки в строке
Поиск подстроки в строке (англ. String searching algorithm) — класс алгоритмов над строками, которые позволяют найти паттерн (needle) в тексте (haystack).
Классификация алгоритмов поиска подстроки в строке
Сравнение — «чёрный ящик»
Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста.
- Позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо.
- Не выдается точка, в которой произошло несовпадение.
По порядку сравнения паттерна в тексте
Прямой
- Отсутсвие регрессии на «плохих» данных.
- Не самая хорошая средняя асимптотическая сложность.
Обратный
Паттерн движется по тексту слева на право, но сравнение подстрок происходит справа на лево.
- При несовпадении позволяет перемещать паттерн по строке сразу на несколько символов
Сравнение в необычном порядке
Специфические алгоритмы, основанные, как правило, на некоторых эмпирических наблюдениях над словарём.
По количеству поисковых шаблонов
- Один шаблон (Single pattern algorithms)
- Конечное количество шаблонов (finite set of patterns)
- Бесконечное количество шаблонов (infinite number of patterns) (см. Теория формальных языков)
По необходимости препроцессинга текста
Виды препроцессинга:
Алгоритмы использующие препроцессинг — одни из самых быстрых в этом классе.
Сравнение алгоритмов
- — размер алфавита
- — длина текста
- — длина паттерна
- — размер ответа(кол-во пар)
- — суммарная длина всех паттернов
Название | Среднее | Худшее | Необходимость препроцессинга | Дополнительная память | Кол-во поисковых шаблонов | Порядок сравнения | Описание |
---|---|---|---|---|---|---|---|
Наивный алгоритм (Brute Force algorithm) |
Single | Прямой | Сравнение — «чёрный ящик». Если | достаточно мало по сравнению с , то ассимптотика будет близкой к O(h), что позволяет использовать его на практике в случаях, когда паттерн много меньше текста (например, ctrl+F в браузерах)||||
Алгоритм Бойера-Мура-Хорспула (Horspool algorithm) |
Single | Прямой | В самой простой реализации использует только эвристику стоп-символа и относится к алгоритмом с сравнением — «чёрным ящиком». | ||||
Алгоритм Рабина-Карпа (Karp-Rabin algorithm) |
Single / Finite | Прямой | Данный алгоритм использует хэширование, что снижает скорость в среднем. Можно модифицировать для поиска нескольких паттернов. | ||||
Алгоритм Кнута-Морриса-Пратта (Knuth-Morris-Pratt algorith) |
Single | Прямой | Использует префикс-функцию | ||||
Алгоритм Ахо-Корасик (Aho–Corasick string matching algorithm) |
Finite | Прямой | Строит конечный автомат. Можно хранить таблицу переходов как индексный массив (array), а можно как Красно-черное дерево. В последнем случае уменьшится расход памяти, но ухудшится асимптотика | ||||
Shift-Or algorithm | w — размер машинного слова |
w — размер машинного слова |
Single | Прямой | Использует тот факт, что в современных процессорах битовые сдвиг и или являются атомарными. Эффективен, если n <= w. Иначе деградирует и по памяти, и по сложности. | ||
Алгоритм Бойера-Мура (Boyer-Moore algorithm) |
Single | Обратный | Считается наиболее быстрым из алгоритмов общего назначения. Использует эвристики. | ||||
Алгоритм Чжу-Такаоки (Zhu-Takaoka algorithm) |
Single | Обратный | Оптимизация Бойера-Мура под короткие алфавиты | ||||
Турбо-алгоритм Бойера-Мура (Turbo-BM algorithm) |
Single | Обратный | Не дает регрессии на «плохих» данных. | сравнений в худшем случае. Количество эвристик увеличивается до трёх.||||
Алгоритм поиска подстроки в строке с помощью суффиксного массива | Single | Использует Суффиксный массив. Если использовать Largest common prefix(lcp), то можно увеличить асимптотику до |
Ссылки
- Википедия — Поиск подстроки
- Википедия — String searching algorithm
- ESMAJ — (англ.) Очень много разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны.