Поиск подстроки в строке — различия между версиями
Firespace (обсуждение | вклад) (delete excess algo, add Raita example, add ref to turbo-algorithm) |
Firespace (обсуждение | вклад) (add Z-function and suffix tree) |
||
Строка 55: | Строка 55: | ||
|Прямой | |Прямой | ||
|Сравнение — «чёрный ящик». Если <tex>n</tex> достаточно мало по сравнению с <tex>h</tex>, то ассимптотика будет близкой к O(h), что позволяет использовать его на практике в случаях, когда паттерн много меньше текста (например, ctrl+F в браузерах) | |Сравнение — «чёрный ящик». Если <tex>n</tex> достаточно мало по сравнению с <tex>h</tex>, то ассимптотика будет близкой к O(h), что позволяет использовать его на практике в случаях, когда паттерн много меньше текста (например, ctrl+F в браузерах) | ||
+ | |||
+ | |-align = "center" | ||
+ | |[[Z-функция| Поиск подстроки в строке с помощью Z-функции]] | ||
+ | |<tex>O(h)</tex> | ||
+ | |<tex>O(h)</tex> | ||
+ | |<tex>O(h + n)</tex> | ||
+ | |<tex>O(h + n)</tex> | ||
+ | |Single | ||
+ | |Прямой | ||
+ | |Сам алгоритм поиска описан на [http://e-maxx.ru/algo/z_function#7 e-maxx.ru:z-function] | ||
|- align = "center" | |- align = "center" | ||
Строка 75: | Строка 85: | ||
|Прямой | |Прямой | ||
|Использует [[Префикс-функция| префикс-функцию]] | |Использует [[Префикс-функция| префикс-функцию]] | ||
+ | |||
+ | |-align = "center" | ||
+ | |[[Алгоритм Колусси| Алгоритм Колусси <br>(Colussi algorithm)]] | ||
+ | |<tex>O(h)</tex> | ||
+ | |<tex>O(h)</tex> | ||
+ | |<tex>O(n)</tex> | ||
+ | |<tex>O(n)</tex> | ||
+ | |Single | ||
+ | |Прямой / Обратный | ||
+ | |Оптимизация [[Алгоритм Кнута-Морриса-Пратта| Алгоритма Кнута-Морриса-Пратта]] использует как прямой, так и обратный обход | ||
|- align = "center" | |- align = "center" | ||
Строка 107: | Строка 127: | ||
|-align = "center" | |-align = "center" | ||
− | |[[Алгоритм поиска подстроки в строке с помощью суффиксного массива]] | + | |[[Алгоритм поиска подстроки в строке с помощью суффиксного массива| Поиск подстроки в строке с помощью суффиксного массива <br>(Suffix array)]] |
|<tex>O(n\log h)</tex> | |<tex>O(n\log h)</tex> | ||
|<tex>O(n\log h)</tex> | |<tex>O(n\log h)</tex> | ||
− | |<tex>O( | + | |<tex>O(h)</tex> |
− | |<tex>O( | + | |<tex>O(h)</tex> |
|Single | |Single | ||
|Прямой | |Прямой | ||
− | |Использует [[Суффиксный массив]]. Если использовать [[Алгоритм Касаи и др.| Largest common prefix (lcp)]], то можно увеличить асимптотику до <tex>O(n + log(h))</tex> | + | |Использует [[Суффиксный массив]]. Если использовать [[Алгоритм Касаи и др.| Largest common prefix (lcp)]], то можно увеличить асимптотику до <tex>O(n + log(h))</tex>. Суффиксный массив строится [[Алгоритм Каркайнена-Сандерса| алгоритмом Каркайнена-Сандерса]] |
|-align = "center" | |-align = "center" | ||
− | |[[ | + | |[[Суффиксный бор| Поиск подстроки в строке с помощью суффиксного бора <br>(Suffix tree)]] |
− | |||
− | |||
|<tex>O(n)</tex> | |<tex>O(n)</tex> | ||
|<tex>O(n)</tex> | |<tex>O(n)</tex> | ||
+ | |<tex>O(h^2)</tex> | ||
+ | |<tex>O(h^2)</tex> | ||
|Single | |Single | ||
− | |Прямой | + | |Прямой |
− | | | + | |Можно использовать [[Сжатое суффиксное дерево]] для оптимизации расхода памяти |
|} | |} | ||
Версия 15:46, 8 июня 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 в браузерах)||||
Поиск подстроки в строке с помощью Z-функции | Single | Прямой | Сам алгоритм поиска описан на e-maxx.ru:z-function | ||||
Алгоритм Рабина-Карпа (Karp-Rabin algorithm) |
Single / Finite | Прямой | Данный алгоритм использует хэширование, что снижает скорость в среднем. Можно модифицировать для поиска нескольких паттернов | ||||
Алгоритм Кнута-Морриса-Пратта (Knuth-Morris-Pratt algorith) |
Single | Прямой | Использует префикс-функцию | ||||
Алгоритм Колусси (Colussi algorithm) |
Single | Прямой / Обратный | Оптимизация Алгоритма Кнута-Морриса-Пратта использует как прямой, так и обратный обход | ||||
Алгоритм Ахо-Корасик (Aho–Corasick string matching algorithm) |
Finite | Прямой | Строит конечный автомат. Можно хранить таблицу переходов как индексный массив (array), а можно как Красно-черное дерево. В последнем случае уменьшится расход памяти, но ухудшится асимптотика | ||||
Алгоритм Shift-Or | w — размер машинного слова |
w — размер машинного слова |
Single | Прямой | Использует тот факт, что в современных процессорах битовые сдвиг и или являются атомарными. Эффективен, если n <= w. Иначе деградирует и по памяти, и по сложности | ||
Алгоритм Бойера-Мура (Boyer-Moore algorithm) |
Single | Обратный | Считается наиболее быстрым из алгоритмов общего назначения. Использует эвристики. Существует большое количество оптимизаций[1] | ||||
Поиск подстроки в строке с помощью суффиксного массива (Suffix array) |
Single | Прямой | Использует Суффиксный массив. Если использовать Largest common prefix (lcp), то можно увеличить асимптотику до . Суффиксный массив строится алгоритмом Каркайнена-Сандерса | ||||
Поиск подстроки в строке с помощью суффиксного бора (Suffix tree) |
Single | Прямой | Можно использовать Сжатое суффиксное дерево для оптимизации расхода памяти |
Примечания
Ссылки
- Википедия — Поиск подстроки
- Википедия — String searching algorithm
- ESMAJ — (англ.) Большое количество разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны.