Изменения

Перейти к: навигация, поиск
Нет описания правки
Алгоритм Рабина — Карпа — это алгоритм поиска подстроки в строке, используя хеширование.
===Метод хеширования===
Выберем полиномиальный хеш - <tex>hash(s[1..n]) = (p^{n - 1} s[1] + ... + p^{0} s[n])</tex> mod <tex>r</tex>, где <tex>p</tex> - это некоторое простое число, а <tex>r</tex> - некоторое большое число, чтобы было меньше коллизий (обычно берётся <tex>2^{32}</tex> или <tex>2^{64}</tex>, чтобы модуль брался автоматически - при переполнении типов;). Заметим, что если 2 строчки имеют одинаковый хэш, то они в большинстве таких случаев равны.
Получается : <tex>hash(s[i + 1..i + m]) = p \cdot hash(s[i..i + m - 1]) - p^{m} s[i] + s[i + m]</tex>.
===Алгоритм===
У нас есть шаблон - <tex>p[1..m]</tex>. У нас есть строка - <tex>s[1..n]</tex>. Мы хотим найти все вхождения шаблона в строку.
Следует предподсчитать <tex>p^{m}</tex>.
Псевдо-код:==Псевдокод== '''1:RabinKarp''' function RabinKarp('''string ''' <tex>s[1..n]</tex>, '''string ''' <tex>p[1..m]</tex>) '''2:''' <tex>hp := \leftarrow hash(p[1..m])</tex> '''3:''' <tex>h := \leftarrow hash(s[1..m])</tex> '''4:for''' for <tex>i from \leftarrow 1 </tex> '''to (''' <tex>n - m + 1)</tex> '''5:if''' if <tex>h = hp</tex> '''6:''' <tex>answer.add(i)</tex> '''7:''' h := p <tex>h \leftarrow p \cdot</tex> h - <tex>p^{m}</tex>\cdot hash(s[i] ) + hash(s[i + m])</tex> '''8:if''' if <tex>ans.size = 0 </tex> '''9:return''' return <tex>not </tex> <tex>found</tex> '''10:else''' else '''11:return''' return <tex>answer</tex>
7 строка была получена Новый хеш <tex>h</tex> был получен с помощью быстрого пересчёта хеша. Мы считаем, что <tex>s[n + 1]</tex> - пустой символ.
Посчитаем время ==Время работы.==
Изначальный подсчёт хешей - <tex>O(m)</tex>. В цикле всего <tex>n - m + 1</tex> итераций - каждая выполняется за <tex>O(1)</tex>. Итого - <tex>O(n + m)</tex>.
304
правки

Навигация