Поиск подстроки в строке — различия между версиями
Firespace (обсуждение | вклад) (Новая страница: «''Поиск подстроки в строке'' (''String searching algorithm'') — класс алгоритмов над строками, которые п...») |
Firespace (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
− | ''Поиск подстроки в строке'' (''String searching algorithm'') — класс алгоритмов над строками, которые позволяют найти паттерн (''needle'') в тексте (''haystack''). | + | \''Поиск подстроки в строке'' (англ. ''String searching algorithm'') — класс алгоритмов над строками, которые позволяют найти паттерн (''needle'') в тексте (''haystack''). |
== Классификация алгоритмов поиска подстроки в строке == | == Классификация алгоритмов поиска подстроки в строке == | ||
=== Сравнение — «чёрный ящик» === | === Сравнение — «чёрный ящик» === | ||
− | Во всех алгоритмах этого типа сравнение является | + | Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста. |
* + Позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо. | * + Позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо. | ||
* - Не выдается точка, в которой произошло несовпадение. | * - Не выдается точка, в которой произошло несовпадение. | ||
Строка 12: | Строка 12: | ||
==== Прямой ==== | ==== Прямой ==== | ||
* + Отсутсвие регрессии на «плохих» данных. | * + Отсутсвие регрессии на «плохих» данных. | ||
− | * - Не самая хорошая средняя | + | * - Не самая хорошая средняя асимптотическая сложность. |
==== Обратный ==== | ==== Обратный ==== | ||
− | Паттерн движется по тексту слева на право, но сравнение подстрок происходит | + | Паттерн движется по тексту слева на право, но сравнение подстрок происходит справа на лево. |
* + При несовпадении позволяет перемещать паттерн по строке сразу на несколько символов | * + При несовпадении позволяет перемещать паттерн по строке сразу на несколько символов | ||
Строка 25: | Строка 25: | ||
#Один шаблон (''Single pattern algorithms'') | #Один шаблон (''Single pattern algorithms'') | ||
#Конечное количество шаблонов (''finite set of patterns'') | #Конечное количество шаблонов (''finite set of patterns'') | ||
− | #Бесконечное количество шаблонов ( | + | #Бесконечное количество шаблонов (''infinite number of patterns'') (см. [[Теория формальных языков]], [http://en.wikipedia.org/wiki/Regular_expression regexp]) |
=== По необходимости препроцессинга текста === | === По необходимости препроцессинга текста === | ||
Строка 33: | Строка 33: | ||
*[[Бор]] | *[[Бор]] | ||
*[[Суффиксный_массив]] | *[[Суффиксный_массив]] | ||
− | Алгоритмы | + | Алгоритмы использующие препроцессинг — одни из самых быстрых в этом классе. |
== Сравнение алгоритмов == | == Сравнение алгоритмов == | ||
Строка 44: | Строка 44: | ||
{|class="wikitable" | {|class="wikitable" | ||
|+ | |+ | ||
− | !width="25%"|Название !! width=" | + | !width="25%"|Название !! width="5%"| Среднее !! width="5%"| Худшее !! width="5%"|Необходимость препроцессинга !! width="5%"| Дополнительная память !! width="10%"| Кол-во поисковых шаблонов !! width="10%"| Порядок сравнения !! width="35%"| Описание |
|- align = "center" | |- align = "center" | ||
Строка 57: | Строка 57: | ||
|- align = "center" | |- align = "center" | ||
− | |[http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180 | + | |[http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180 Алгоритм Бойера-Мура-Хорспула <br>(Horspool algorithm)] |
|<tex>O(nh)</tex> | |<tex>O(nh)</tex> | ||
|<tex>O(nh)</tex> | |<tex>O(nh)</tex> | ||
Строка 71: | Строка 71: | ||
|Да <br> <tex>O(n)</tex> | |Да <br> <tex>O(n)</tex> | ||
|<tex>O(1)</tex> | |<tex>O(1)</tex> | ||
− | |Single | + | |Single / Finite |
|Прямой | |Прямой | ||
− | |Данный алгоритм использует хэширование, что снижает скорость в среднем. | + | |Данный алгоритм использует хэширование, что снижает скорость в среднем. Можно модифицировать для поиска нескольких паттернов. |
|- align = "center" | |- align = "center" | ||
Строка 91: | Строка 91: | ||
|Да <br> <tex>O(m)</tex> | |Да <br> <tex>O(m)</tex> | ||
|<tex>O(m\sigma)</tex> | |<tex>O(m\sigma)</tex> | ||
− | | | + | |Finite |
+ | |Прямой | ||
+ | |Строит конечный автомат. Можно хранить таблицу переходов как индексный массив (array), а можно как [[Красно-черное дерево]]. В последнем случае уменьшится расход памяти, но ухудшится асимптотика | ||
+ | |||
+ | |-align = "center" | ||
+ | |[http://www-igm.univ-mlv.fr/~lecroq/string/node6.html#SECTION0060 Shift-Or algorithm] | ||
+ | |<tex>O(h)</tex> <br> w — размер машинного слова | ||
+ | |<tex>O(h \cdot ceil(n / w))</tex> <br> w — размер машинного слова | ||
+ | |Да <br> <tex>O(n + \sigma)</tex> | ||
+ | |<tex>O(n + \sigma)</tex> | ||
+ | |Single | ||
|Прямой | |Прямой | ||
− | | | + | |Использует тот факт, что в современных процессорах битовые сдвиг и или являются атомарными. Эффективен, если n <= w. Иначе деградирует и по памяти, и по сложности. |
+ | |||
+ | |-align = "center" | ||
+ | |[[Алгоритм Бойера-Мура| Алгоритм Бойера-Мура <br>(Boyer-Moore algorithm)]] | ||
+ | |<tex>O(h)</tex> | ||
+ | |<tex>O(hn)</tex> | ||
+ | |Да <br> <tex>O(n + \sigma)</tex> | ||
+ | |<tex>O(n + \sigma)</tex> | ||
+ | |Single | ||
+ | |Обратный | ||
+ | |Считается наиболее быстрым из алгоритмов общего назначения. Использует эвристики. | ||
+ | |||
+ | |-align = "center" | ||
+ | |[http://www-igm.univ-mlv.fr/~lecroq/string/node20.html#SECTION00200 Алгоритм Чжу-Такаоки <br>(Zhu-Takaoka algorithm)] | ||
+ | |<tex>O(h)</tex> | ||
+ | |<tex>O(hn)</tex> | ||
+ | |Да <br> <tex>O(n + \sigma^2)</tex> | ||
+ | |<tex>O(n + \sigma^2)</tex> | ||
+ | |Single | ||
+ | |Обратный | ||
+ | |Оптимизация Бойера-Мура под короткие алфавиты | ||
+ | |||
+ | |-align = "center" | ||
+ | |[http://www-igm.univ-mlv.fr/~lecroq/string/node15.html#SECTION00150 Турбо-алгоритм Бойера-Мура <br>(Turbo-BM algorithm)] | ||
+ | |<tex>O(h)</tex> | ||
+ | |<tex>O(h)</tex> | ||
+ | |Да <br> <tex>O(n + \sigma)</tex> | ||
+ | |<tex>O(n + \sigma)</tex> | ||
+ | |Single | ||
+ | |Обратный | ||
+ | |Не дает регрессии на «плохих» данных. <tex>2h</tex> сравнений в худшем случае. Количество эвристик увеличивается до трёх. | ||
+ | |||
+ | |-align = "center" | ||
+ | |[[Алгоритм поиска подстроки в строке с помощью суффиксного массива]] | ||
+ | |<tex>O(nlog(h))</tex> | ||
+ | |<tex>O(nlog(h))</tex> | ||
+ | |Да <br> <tex>O(n)</tex> | ||
+ | |<tex>O(nlog^2(n))</tex> | ||
+ | |Single | ||
+ | | | ||
+ | |Использует [[Суффиксный массив]]. Если использовать [[Алгоритм Касаи и др.| Largest common prefix(lcp)]], то можно увеличить асимптотику до <tex>O(n + log(h))</tex> | ||
|} | |} | ||
+ | |||
+ | == Ссылки == | ||
+ | * http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8 | ||
+ | * http://en.wikipedia.org/wiki/String_searching_algorithm | ||
+ | * http://www-igm.univ-mlv.fr/~lecroq/string/index.html — (англ.) Очень много разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны. | ||
+ | |||
+ | [[Категория: Дискретная математика и алгоритмы]] | ||
+ | [[Категория: Поиск подстроки в строке]] |
Версия 21:49, 5 июня 2014
\Поиск подстроки в строке (англ. String searching algorithm) — класс алгоритмов над строками, которые позволяют найти паттерн (needle) в тексте (haystack).
Классификация алгоритмов поиска подстроки в строке
Сравнение — «чёрный ящик»
Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста.
- + Позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо.
- - Не выдается точка, в которой произошло несовпадение.
По порядку сравнения паттерна в тексте
Прямой
- + Отсутсвие регрессии на «плохих» данных.
- - Не самая хорошая средняя асимптотическая сложность.
Обратный
Паттерн движется по тексту слева на право, но сравнение подстрок происходит справа на лево.
- + При несовпадении позволяет перемещать паттерн по строке сразу на несколько символов
Сравнение в необычном порядке
Специфические алгоритмы, основанные, как правило, на некоторых эмпирических наблюдениях над словарём.
По количеству поисковых шаблонов
- Один шаблон (Single pattern algorithms)
- Конечное количество шаблонов (finite set of patterns)
- Бесконечное количество шаблонов (infinite number of patterns) (см. Теория формальных языков, regexp)
По необходимости препроцессинга текста
Виды препроцессинга:
Алгоритмы использующие препроцессинг — одни из самых быстрых в этом классе.
Сравнение алгоритмов
- — размер алфавита
- — длина текста
- — длина паттерна
- — размер ответа(кол-во пар)
- — суммарная длина всх паттернов
Название | Среднее | Худшее | Необходимость препроцессинга | Дополнительная память | Кол-во поисковых шаблонов | Порядок сравнения | Описание |
---|---|---|---|---|---|---|---|
Наивный алгоритм (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), то можно увеличить асимптотику до |
Ссылки
- http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8
- http://en.wikipedia.org/wiki/String_searching_algorithm
- http://www-igm.univ-mlv.fr/~lecroq/string/index.html — (англ.) Очень много разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны.