Изменения

Перейти к: навигация, поиск

Поиск подстроки в строке

1328 байт добавлено, 05:10, 27 мая 2018
Сравнение алгоритмов
'''Поиск подстроки в строке''' (англ. ''String searching algorithm'') — класс алгоритмов над строками, которые позволяют найти паттерн (''needlepattern'') в тексте (''haystacktext'').
== Классификация алгоритмов поиска подстроки в строке ==
=== Сравнение — «чёрный ящик» ===
Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста.  Преимущества:* + Позволяет позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо.  Недостатки:* - Не не выдается точка, в которой произошло несовпадение.
=== По порядку сравнения паттерна в тексте ===
==== Прямой ====
==== Прямой ====Преимущества:* + Отсутсвие отсутствие регрессии на «плохих» данных. Недостатки:* - Не не самая хорошая средняя асимптотическая сложность.
==== Обратный ====
Паттерн движется по тексту слева на правонаправо, но сравнение подстрок происходит справа на левоналевоПреимущества:* + При при несовпадении позволяет перемещать паттерн по строке сразу на несколько символов. Недостатки:* производительность сильно зависит от данных.
==== Сравнение в необычном порядке ====
Специфические алгоритмы, основанные, как правило, на некоторых эмпирических наблюдениях над словарём. <ref>Например, [[Wikipedia:en:Raita Algorithm| Алгоритм Райты (англ.)]]</ref>
=== По количеству поисковых шаблонов ===
#Один Сколько поисковых шаблонов может обработать алгоритм за один раз. * один шаблон (англ. ''Single single pattern algorithms'')#Конечное * конечное количество шаблонов (англ. ''finite set of patterns'')#Бесконечное * бесконечное количество шаблонов (англ. ''infinite number of patterns'') (см. [[Теория формальных языков]], [http://en.wikipedia.org/wiki/Regular_expression regexp])
=== По необходимости препроцессинга текста ===
*[[Z-функция]]
*[[Бор]]
*[[Суффиксный_массивСуффиксный массив]]Алгоритмы , использующие препроцессинг — одни из самых быстрых в этом классе.
== Сравнение алгоритмов ==
*<tex>|\Sigma| = \sigma</tex>­ — размер алфавита
*<tex>|haystacktext| = ht</tex> — длина текста*<tex>|needlepattern| = np</tex> — длина паттерна
*<tex>a</tex> — размер ответа(кол-во пар)
*<tex>m</tex> — суммарная длина всх всех паттернов
{|class="wikitable"
|+
!width="25%"|Название !! width="5%"| Среднее !! width="5%"| Худшее !! width="5%"|Необходимость препроцессинга Препроцессинг !! width="5%"| Дополнительная память !! width="10%"| Кол-во поисковых шаблонов !! width="10%"| Порядок сравнения !! width="35%"| Описание
|- align = "center"
|[[Наивный алгоритм поиска подстроки в строке| Наивный алгоритм <br>(Brute Force algorithm)]]
|<tex>O(n p \cdot (h t - np))</tex>|<tex>O(nt^2)</tex>|Нет
|<tex>O(1)</tex>
|Single
|Прямой
|Сравнение — «чёрный ящик». Если <tex>np</tex> достаточно мало по сравнению с <tex>ht</tex>, то ассимптотика асимптотика будет близкой к <tex>O(ht)</tex>, что позволяет использовать его на практике в случаях, когда паттерн много меньше текста (например, ctrlCtrl+F в браузерах)
|- align = "center"|[http://www[Z-igm.univфункция| Поиск подстроки в строке с помощью Z-mlv.fr/~lecroq/string/node18.html#SECTION00180 Алгоритм Бойера-Мура-Хорспула <br>(Horspool algorithm)функции]]|<tex>O(nht)</tex>|<tex>O(nht)</tex>|Да <br> <tex>O(n p + \sigmat)</tex>|<tex>O(\sigmap)</tex>
|Single
|Прямой
|В самой простой реализации использует только эвристику стоп-символа и относится к алгоритмом с сравнением — «чёрным ящиком».  
|- align = "center"
|[[Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа| Алгоритм Рабина-Карпа <br>(Karp-Rabin algorithm)]]
|<tex>O(n p + ht)</tex>|<tex>O(nhpt)</tex>|Да <br> <tex>O(np)</tex>
|<tex>O(1)</tex>
|Single / Finite
|Прямой
|Данный алгоритм использует хэширование, что снижает скорость в среднем. Можно модифицировать для поиска нескольких паттернов.
|- align = "center"
|[[Алгоритм Кнута-Морриса-Пратта| Алгоритм Кнута-Морриса-Пратта <br>(Knuth-Morris-Pratt algorith)]]
|<tex>O(n p + ht)</tex>|<tex>O(n p + ht)</tex>|Да <br> <tex>O(np)</tex>|<tex>O(np)</tex>
|Single
|Прямой
|Использует [[Префикс-функция| префикс-функцию]]
 
|-align = "center"
|[[Алгоритм Колусси| Алгоритм Колусси <br>(Colussi algorithm)]]
|<tex>O(t)</tex>
|<tex>O(t)</tex>
|<tex>O(p)</tex>
|<tex>O(p)</tex>
|Single
|Прямой / Обратный
|Оптимизация [[Алгоритм Кнута-Морриса-Пратта| Алгоритма Кнута-Морриса-Пратта]] использует как прямой, так и обратный обход
|- align = "center"
|[[Алгоритм Ахо-Корасик| Алгоритм Ахо-Корасик <br>(Aho–Corasick string matching algorithm)]]
|<tex>O(m + h t + a)</tex>|<tex>O(ht)</tex>|Да <br> <tex>O(m)</tex>
|<tex>O(m\sigma)</tex>
|Finite
|-align = "center"
|[http://www-igm.univ-mlv.fr/~lecroq/string/node6.html#SECTION0060 [Алгоритм Shift-Or algorithm]]|<tex>O(ht)</tex> <br> w — размер машинного слова|<tex>O(h t \cdot ceil(\dfrac{n / }{w)})</tex> <br> <tex> w </tex> — размер машинного слова|Да <br> <tex>O(n p + \sigma)</tex>|<tex>O(n p + \sigma)</tex>
|Single
|Прямой
|Использует тот факт, что в современных процессорах битовые сдвиг и или являются атомарными. Эффективен, если n <= tex>p \leqslant w</tex>. Иначе деградирует и по памяти, и по сложности.
|-align = "center"
|[[Алгоритм Бойера-Мура| Алгоритм Бойера-Мура <br>(Boyer-Moore algorithm)]]
|<tex>O(ht)</tex>|<tex>O(hnpt)</tex>|Да <br> <tex>O(n p + \sigma)</tex>|<tex>O(n p + \sigma)</tex>
|Single
|Обратный
|Считается наиболее быстрым из алгоритмов общего назначения. Использует эвристики.Существует большое количество оптимизаций<ref>Например, [http://www-igm.univ-mlv.fr/~lecroq/string/node15.html#SECTION00150 Турбо-алгоритм Бойера-Мура <br>(Turbo-BM algorithm)]</ref>
|-align = "center"
|[http://www-igm.univ-mlv.fr/~lecroq/string/node20.html#SECTION00200 [Алгоритм Чжу-Такаоки поиска подстроки в строке с помощью суффиксного массива| Поиск подстроки в строке с помощью суффиксного массива <br>(Zhu-Takaoka algorithmSuffix array)]]|<tex>O(hp\log t)</tex>|<tex>O(hnp\log t)</tex>|Да <br> <tex>O(n + \sigma^2t)</tex>|<tex>O(n + \sigma^2t)</tex>
|Single
|ОбратныйПрямой|Оптимизация БойераИспользует [[Суффиксный массив]]. Если использовать [[Алгоритм Касаи и др.| Largest common prefix (lcp)]], то можно уменьшить асимптотику до <tex>O(p + \log t)</tex>. Суффиксный массив можно строить[[Построение суффиксного массива с помощью стандартных методов сортировки| стандартными способами]] или [[Алгоритм Карккайнена-Сандерса| алгоритмом Карккайнена-Сандерса]]. Асимптотика приведена для построения суффиксного массива с помощью алгоритма Карккайнена-Мура под короткие алфавитыСандерса
|-align = "center"
|[http://www-igm.univ-mlv.fr/~lecroq/string/node15.html#SECTION00150 Турбо-алгоритм Бойера-Мура [Сжатое суффиксное дерево| Поиск подстроки в строке с помощью суффиксного дерева <br>(Turbo-BM algorithmSuffix tree)]]|<tex>O(hp)</tex>|<tex>O(hp)</tex>|Да <br> <tex>O(n + \sigmat)</tex>|<tex>O(n + \sigmat)</tex>
|Single
|ОбратныйПрямой|Не дает регрессии на «плохих» данных. <tex>2h</tex> сравнений Позволяет выполнять поиск подстроки в худшем случае. Количество эвристик увеличивается до трёх.строке за линейное время
|-align = "center"|[[Алгоритм поиска подстроки в строке с помощью суффиксного массиваАпостолико-Крочемора| Алгоритм Апостолико-Крочемора <br>( Apostolico-Crochemore algorithm)]]|<tex>O(nlog(h)t)</tex>|<tex>O(nlog(h)t)</tex>|Да <br> <tex>O(np)</tex>|<tex>O(nlog^2(n)p)</tex>
|Single
|Прямой|Использует [[Суффиксный массив]]. Если использовать [[Алгоритм Касаи и др.| Largest common prefix(lcp)]], то можно увеличить асимптотику до В худшем случае выполнит <tex>O(\dfrac{3}{2} n + log(h))</tex>сравнений.
|}
== Ссылки Примечания == <references /> == Источники информации ==
* [[wikipedia:ru:Поиск_подстроки | Википедия {{---}} Поиск подстроки]]
* [[wikipediaWikipedia:en:String_searching_algorithm | Википедия {{---}} String searching algorithm]]* [http://www-igm.univ-mlv.fr/~lecroq/string/index.html ESMAJ] {{---}} Очень много — (англ.) Большое количество разных алгоритмов поиска подстроки в строке. Многие из них в данной статье не описаны.
[[Категория: Дискретная математика и алгоритмы]]
[[Категория: Поиск подстроки в строке]]
Анонимный участник

Навигация