Алгоритм поиска подстроки в строке с помощью суффиксного массива — различия между версиями
| Строка 1: | Строка 1: | ||
| − | Пусть у нас есть образец <tex> P </tex>, строка <tex> S </tex> и [[Суффиксный массив|суффиксный массив]] <tex> sufArray </tex>. Мы хотим найти все вхождения данного образца в данную строку | + | Пусть у нас есть образец <tex> P </tex>, строка <tex> S </tex> и [[Суффиксный массив|суффиксный массив]] <tex> sufArray </tex>. Мы хотим найти все вхождения данного образца в данную строку. |
==Решение при помощи бинарного поиска== | ==Решение при помощи бинарного поиска== | ||
| Строка 5: | Строка 5: | ||
Понятно, что если образец <tex> P </tex> входит в строку <tex> S </tex>, то он является префиксом какого-нибудь ее суффикса. Если вхождений несколько, то в суффиксном массиве <tex> sufArray </tex> они будут находиться рядом друг с другом. Получается, что задача сводится к бинарному поиску в упорядоченном массиве. <br> | Понятно, что если образец <tex> P </tex> входит в строку <tex> S </tex>, то он является префиксом какого-нибудь ее суффикса. Если вхождений несколько, то в суффиксном массиве <tex> sufArray </tex> они будут находиться рядом друг с другом. Получается, что задача сводится к бинарному поиску в упорядоченном массиве. <br> | ||
| − | Определим границы, в которых лежат вхождения. | + | Определим границы, в которых лежат вхождения. На первом шаге сравниваем суффикс <tex> sufArray[|S| / 2] </tex> и образец <tex> P </tex>. Если суффикс лексикографически больше, то необходимо идти в левую половину <tex> sufArray </tex>, иначе в правую. На следующем шаге аналогично проверяем суффикс по середине от половины суффискного массива, затем от четверти и так далее. В результате проделанной работы получим левую и правую границы <tex> L </tex> и <tex> R </tex> соответственно. В этих границах и лежат вхождения образца <tex> P </tex> в строку <tex> S </tex>. <br> |
| − | Время лексикографического сравнения образца <tex> P </tex> с суффиксом <tex> S </tex> равно длине их общего префикса и не | + | Время лексикографического сравнения образца <tex> P </tex> с суффиксом <tex> S </tex> равно длине их общего префикса и не может превышать <tex> |P| </tex>. Поэтому время работы алгоритма равно <tex> O(|P|log|S|) </tex>. |
| + | |||
| + | ==Улучшение бинарного поиска== | ||
Версия 05:24, 1 мая 2011
Пусть у нас есть образец , строка и суффиксный массив . Мы хотим найти все вхождения данного образца в данную строку.
Решение при помощи бинарного поиска
Понятно, что если образец входит в строку , то он является префиксом какого-нибудь ее суффикса. Если вхождений несколько, то в суффиксном массиве они будут находиться рядом друг с другом. Получается, что задача сводится к бинарному поиску в упорядоченном массиве.
Определим границы, в которых лежат вхождения. На первом шаге сравниваем суффикс и образец . Если суффикс лексикографически больше, то необходимо идти в левую половину , иначе в правую. На следующем шаге аналогично проверяем суффикс по середине от половины суффискного массива, затем от четверти и так далее. В результате проделанной работы получим левую и правую границы и соответственно. В этих границах и лежат вхождения образца в строку .
Время лексикографического сравнения образца с суффиксом равно длине их общего префикса и не может превышать . Поэтому время работы алгоритма равно .