Поиск подстроки в строке — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Ссылки)
(small decor changes)
Строка 5: Строка 5:
  
 
Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста.  
 
Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста.  
* + Позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо.  
+
: <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'') (см. [[Теория формальных языков]], [http://en.wikipedia.org/wiki/Regular_expression regexp])
+
#Бесконечное количество шаблонов (''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>
|Да <br> <tex>O(n + \sigma)</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>
|Да <br> <tex>O(n)</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>
|Да <br> <tex>O(n)</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>
+
|<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 — размер машинного слова
|Да <br> <tex>O(n + \sigma)</tex>
+
|<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>
|Да <br> <tex>O(n + \sigma)</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>
|Да <br> <tex>O(n + \sigma^2)</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>
|Да <br> <tex>O(n + \sigma)</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(nlog(h))</tex>
+
|<tex>O(n\log h)</tex>
|<tex>O(nlog(h))</tex>
+
|<tex>O(n\log h)</tex>
|Да <br> <tex>O(n)</tex>
+
|<tex>O(n)</tex>
|<tex>O(nlog^2(n))</tex>
+
|<tex>O(n\log^2 n)</tex>
 
|Single
 
|Single
 
|
 
|
Строка 148: Строка 148:
 
== Ссылки ==
 
== Ссылки ==
 
* [[wikipedia:ru:Поиск_подстроки | Википедия {{---}} Поиск подстроки]]
 
* [[wikipedia:ru:Поиск_подстроки | Википедия {{---}} Поиск подстроки]]
* [[wikipedia:en:String_searching_algorithm | Википедия {{---}} String searching algorithm]]
+
* [[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).

Классификация алгоритмов поиска подстроки в строке

Сравнение — «чёрный ящик»

Во всех алгоритмах этого типа сравнение является «чёрным ящиком» для программиста.

[math]+[/math] Позволяет использовать стандартные функции сравнения участков памяти (man *cmp(3)), которые, зачастую, оптимизированы под конкретное железо.
[math]-[/math] Не выдается точка, в которой произошло несовпадение.

По порядку сравнения паттерна в тексте

Прямой

[math]+[/math] Отсутсвие регрессии на «плохих» данных.
[math]-[/math] Не самая хорошая средняя асимптотическая сложность.

Обратный

Паттерн движется по тексту слева на право, но сравнение подстрок происходит справа на лево.

[math]+[/math] При несовпадении позволяет перемещать паттерн по строке сразу на несколько символов

Сравнение в необычном порядке

Специфические алгоритмы, основанные, как правило, на некоторых эмпирических наблюдениях над словарём.

По количеству поисковых шаблонов

  1. Один шаблон (Single pattern algorithms)
  2. Конечное количество шаблонов (finite set of patterns)
  3. Бесконечное количество шаблонов (infinite number of patterns) (см. Теория формальных языков)

По необходимости препроцессинга текста

Виды препроцессинга:

Алгоритмы использующие препроцессинг — одни из самых быстрых в этом классе.

Сравнение алгоритмов

  • [math]|\Sigma| = \sigma[/math]­ — размер алфавита
  • [math]|haystack| = h[/math] — длина текста
  • [math]|needle| = n[/math] — длина паттерна
  • [math]a[/math] — размер ответа(кол-во пар)
  • [math]m[/math] — суммарная длина всех паттернов
Название Среднее Худшее Необходимость препроцессинга Дополнительная память Кол-во поисковых шаблонов Порядок сравнения Описание
Наивный алгоритм
(Brute Force algorithm)
[math]O(n \cdot (h - n))[/math] [math]O(n^2)[/math] [math]O(1)[/math] Single Прямой Сравнение — «чёрный ящик». Если [math]n[/math] достаточно мало по сравнению с [math]h[/math], то ассимптотика будет близкой к O(h), что позволяет использовать его на практике в случаях, когда паттерн много меньше текста (например, ctrl+F в браузерах)
Алгоритм Бойера-Мура-Хорспула
(Horspool algorithm)
[math]O(nh)[/math] [math]O(nh)[/math] [math]O(n + \sigma)[/math] [math]O(\sigma)[/math] Single Прямой В самой простой реализации использует только эвристику стоп-символа и относится к алгоритмом с сравнением — «чёрным ящиком».
Алгоритм Рабина-Карпа
(Karp-Rabin algorithm)
[math]O(n + h)[/math] [math]O(nh)[/math] [math]O(n)[/math] [math]O(1)[/math] Single / Finite Прямой Данный алгоритм использует хэширование, что снижает скорость в среднем. Можно модифицировать для поиска нескольких паттернов.
Алгоритм Кнута-Морриса-Пратта
(Knuth-Morris-Pratt algorith)
[math]O(n + h)[/math] [math]O(n + h)[/math] [math]O(n)[/math] [math]O(n)[/math] Single Прямой Использует префикс-функцию
Алгоритм Ахо-Корасик
(Aho–Corasick string matching algorithm)
[math]O(m + h + a)[/math] [math]O(h)[/math]
[math]O(m)[/math]
[math]O(m\sigma)[/math] Finite Прямой Строит конечный автомат. Можно хранить таблицу переходов как индексный массив (array), а можно как Красно-черное дерево. В последнем случае уменьшится расход памяти, но ухудшится асимптотика
Shift-Or algorithm [math]O(h)[/math]
w — размер машинного слова
[math]O(h \cdot ceil(n / w))[/math]
w — размер машинного слова
[math]O(n + \sigma)[/math] [math]O(n + \sigma)[/math] Single Прямой Использует тот факт, что в современных процессорах битовые сдвиг и или являются атомарными. Эффективен, если n <= w. Иначе деградирует и по памяти, и по сложности.
Алгоритм Бойера-Мура
(Boyer-Moore algorithm)
[math]O(h)[/math] [math]O(hn)[/math] [math]O(n + \sigma)[/math] [math]O(n + \sigma)[/math] Single Обратный Считается наиболее быстрым из алгоритмов общего назначения. Использует эвристики.
Алгоритм Чжу-Такаоки
(Zhu-Takaoka algorithm)
[math]O(h)[/math] [math]O(hn)[/math] [math]O(n + \sigma^2)[/math] [math]O(n + \sigma^2)[/math] Single Обратный Оптимизация Бойера-Мура под короткие алфавиты
Турбо-алгоритм Бойера-Мура
(Turbo-BM algorithm)
[math]O(h)[/math] [math]O(h)[/math] [math]O(n + \sigma)[/math] [math]O(n + \sigma)[/math] Single Обратный Не дает регрессии на «плохих» данных. [math]2h[/math] сравнений в худшем случае. Количество эвристик увеличивается до трёх.
Алгоритм поиска подстроки в строке с помощью суффиксного массива [math]O(n\log h)[/math] [math]O(n\log h)[/math] [math]O(n)[/math] [math]O(n\log^2 n)[/math] Single Использует Суффиксный массив. Если использовать Largest common prefix(lcp), то можно увеличить асимптотику до [math]O(n + log(h))[/math]

Ссылки