Поиск подстроки в строке — различия между версиями
(→Ссылки) |
Firespace (обсуждение | вклад) (small decor changes) |
||
Строка 5: | Строка 5: | ||
Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста. | Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста. | ||
− | + | : <tex>+</tex> Позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо. | |
− | + | : <tex>-</tex> Не выдается точка, в которой произошло несовпадение. | |
=== По порядку сравнения паттерна в тексте === | === По порядку сравнения паттерна в тексте === | ||
==== Прямой ==== | ==== Прямой ==== | ||
− | + | : <tex>+</tex> Отсутсвие регрессии на «плохих» данных. | |
− | + | : <tex>-</tex> Не самая хорошая средняя асимптотическая сложность. | |
==== Обратный ==== | ==== Обратный ==== | ||
Паттерн движется по тексту слева на право, но сравнение подстрок происходит справа на лево. | Паттерн движется по тексту слева на право, но сравнение подстрок происходит справа на лево. | ||
− | + | : <tex>+</tex> При несовпадении позволяет перемещать паттерн по строке сразу на несколько символов | |
==== Сравнение в необычном порядке ==== | ==== Сравнение в необычном порядке ==== | ||
Строка 25: | Строка 25: | ||
#Один шаблон (''Single pattern algorithms'') | #Один шаблон (''Single pattern algorithms'') | ||
#Конечное количество шаблонов (''finite set of patterns'') | #Конечное количество шаблонов (''finite set of patterns'') | ||
− | #Бесконечное количество шаблонов (''infinite number of patterns'') (см. [[Теория формальных языков] | + | #Бесконечное количество шаблонов (''infinite number of patterns'') (см. [[Теория формальных языков]]) |
=== По необходимости препроцессинга текста === | === По необходимости препроцессинга текста === | ||
Строка 32: | Строка 32: | ||
*[[Z-функция]] | *[[Z-функция]] | ||
*[[Бор]] | *[[Бор]] | ||
− | *[[ | + | *[[Суффиксный массив]] |
Алгоритмы использующие препроцессинг — одни из самых быстрых в этом классе. | Алгоритмы использующие препроцессинг — одни из самых быстрых в этом классе. | ||
Строка 40: | Строка 40: | ||
*<tex>|needle| = n</tex> — длина паттерна | *<tex>|needle| = n</tex> — длина паттерна | ||
*<tex>a</tex> — размер ответа(кол-во пар) | *<tex>a</tex> — размер ответа(кол-во пар) | ||
− | *<tex>m</tex> — суммарная длина | + | *<tex>m</tex> — суммарная длина всех паттернов |
{|class="wikitable" | {|class="wikitable" | ||
Строка 50: | Строка 50: | ||
|<tex>O(n \cdot (h - n))</tex> | |<tex>O(n \cdot (h - n))</tex> | ||
|<tex>O(n^2)</tex> | |<tex>O(n^2)</tex> | ||
− | | | + | | |
|<tex>O(1)</tex> | |<tex>O(1)</tex> | ||
|Single | |Single | ||
Строка 60: | Строка 60: | ||
|<tex>O(nh)</tex> | |<tex>O(nh)</tex> | ||
|<tex>O(nh)</tex> | |<tex>O(nh)</tex> | ||
− | | | + | |<tex>O(n + \sigma)</tex> |
|<tex>O(\sigma)</tex> | |<tex>O(\sigma)</tex> | ||
|Single | |Single | ||
Строка 69: | Строка 69: | ||
|<tex>O(n + h)</tex> | |<tex>O(n + h)</tex> | ||
|<tex>O(nh)</tex> | |<tex>O(nh)</tex> | ||
− | | | + | |<tex>O(n)</tex> |
|<tex>O(1)</tex> | |<tex>O(1)</tex> | ||
|Single / Finite | |Single / Finite | ||
Строка 79: | Строка 79: | ||
|<tex>O(n + h)</tex> | |<tex>O(n + h)</tex> | ||
|<tex>O(n + h)</tex> | |<tex>O(n + h)</tex> | ||
− | | | + | |<tex>O(n)</tex> |
|<tex>O(n)</tex> | |<tex>O(n)</tex> | ||
|Single | |Single | ||
Строка 89: | Строка 89: | ||
|<tex>O(m + h + a)</tex> | |<tex>O(m + h + a)</tex> | ||
|<tex>O(h)</tex> | |<tex>O(h)</tex> | ||
− | | | + | |<br> <tex>O(m)</tex> |
|<tex>O(m\sigma)</tex> | |<tex>O(m\sigma)</tex> | ||
|Finite | |Finite | ||
Строка 99: | Строка 99: | ||
|<tex>O(h)</tex> <br> w — размер машинного слова | |<tex>O(h)</tex> <br> w — размер машинного слова | ||
|<tex>O(h \cdot ceil(n / w))</tex> <br> w — размер машинного слова | |<tex>O(h \cdot ceil(n / w))</tex> <br> w — размер машинного слова | ||
− | | | + | |<tex>O(n + \sigma)</tex> |
|<tex>O(n + \sigma)</tex> | |<tex>O(n + \sigma)</tex> | ||
|Single | |Single | ||
Строка 109: | Строка 109: | ||
|<tex>O(h)</tex> | |<tex>O(h)</tex> | ||
|<tex>O(hn)</tex> | |<tex>O(hn)</tex> | ||
− | | | + | |<tex>O(n + \sigma)</tex> |
|<tex>O(n + \sigma)</tex> | |<tex>O(n + \sigma)</tex> | ||
|Single | |Single | ||
Строка 119: | Строка 119: | ||
|<tex>O(h)</tex> | |<tex>O(h)</tex> | ||
|<tex>O(hn)</tex> | |<tex>O(hn)</tex> | ||
− | | | + | |<tex>O(n + \sigma^2)</tex> |
|<tex>O(n + \sigma^2)</tex> | |<tex>O(n + \sigma^2)</tex> | ||
|Single | |Single | ||
Строка 129: | Строка 129: | ||
|<tex>O(h)</tex> | |<tex>O(h)</tex> | ||
|<tex>O(h)</tex> | |<tex>O(h)</tex> | ||
− | | | + | |<tex>O(n + \sigma)</tex> |
|<tex>O(n + \sigma)</tex> | |<tex>O(n + \sigma)</tex> | ||
|Single | |Single | ||
Строка 137: | Строка 137: | ||
|-align = "center" | |-align = "center" | ||
|[[Алгоритм поиска подстроки в строке с помощью суффиксного массива]] | |[[Алгоритм поиска подстроки в строке с помощью суффиксного массива]] | ||
− | |<tex>O( | + | |<tex>O(n\log h)</tex> |
− | |<tex>O( | + | |<tex>O(n\log h)</tex> |
− | | | + | |<tex>O(n)</tex> |
− | |<tex>O( | + | |<tex>O(n\log^2 n)</tex> |
|Single | |Single | ||
| | | | ||
Строка 148: | Строка 148: | ||
== Ссылки == | == Ссылки == | ||
* [[wikipedia:ru:Поиск_подстроки | Википедия {{---}} Поиск подстроки]] | * [[wikipedia:ru:Поиск_подстроки | Википедия {{---}} Поиск подстроки]] | ||
− | * [[ | + | * [[Wikipedia:en:String_searching_algorithm | Википедия {{---}} String searching algorithm]] |
− | * [http://www-igm.univ-mlv.fr/~lecroq/string/index.html ESMAJ] | + | * [http://www-igm.univ-mlv.fr/~lecroq/string/index.html ESMAJ] — (англ.) Очень много разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны. |
[[Категория: Дискретная математика и алгоритмы]] | [[Категория: Дискретная математика и алгоритмы]] | ||
[[Категория: Поиск подстроки в строке]] | [[Категория: Поиск подстроки в строке]] |
Версия 00:49, 6 июня 2014
Поиск подстроки в строке (англ. 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 — (англ.) Очень много разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны.