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