Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа — различия между версиями
Vasin (обсуждение | вклад) |
Vasin (обсуждение | вклад) (→Псевдокод) |
||
| Строка 31: | Строка 31: | ||
<tex>answer.add(i)</tex> | <tex>answer.add(i)</tex> | ||
<tex>h \leftarrow p \cdot h - p^{m} \cdot hash(s[i]) + hash(s[i + m])</tex> | <tex>h \leftarrow p \cdot h - p^{m} \cdot hash(s[i]) + hash(s[i + m])</tex> | ||
| − | '''if''' <tex> | + | '''if''' <tex>answer.size = 0</tex> |
'''return''' <tex>not</tex> <tex>found</tex> | '''return''' <tex>not</tex> <tex>found</tex> | ||
'''else''' | '''else''' | ||
Версия 22:06, 24 марта 2012
Алгоритм Рабина — Карпа — это алгоритм поиска подстроки в строке, используя хеширование.
Метод хеширования
Выберем полиномиальный хеш - mod , где - это некоторое простое число, а - некоторое большое число, чтобы было меньше коллизий (обычно берётся или , чтобы модуль брался автоматически - при переполнении типов;). Заметим, что если 2 строчки имеют одинаковый хэш, то они в большинстве таких случаев равны.
Давайте научимся при удалении первого символа строки и добавлении символа в конец считать хеш новой строки при помощи хеша изначальной строки за :
.
.
Получается : .
Алгоритм
У нас есть шаблон - . У нас есть строка - . Мы хотим найти все вхождения шаблона в строку.
Давайте посчитаем и .
И для считаем - сравниваем с . Если они получаются равными - то мы считаем, что подстрока входит в строку (начиная с позиции ;) или мы проверяем, что подстрока является шаблоном, для этого выберем случайные символы из строк и сравним их.
Следует предподсчитать .
Псевдокод
RabinKarp (string , string ) for to if if return else return
Новый хеш был получен с помощью быстрого пересчёта. Мы считаем, что - пустой символ.
Время работы
Изначальный подсчёт хешей - . В цикле всего итераций - каждая выполняется за . Итого - .
Литература
Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — 2-е изд. — М.: Издательский дом «Вильямс», 2007. — С. 1296.