Інформація та теорія
Рабін–Карп знаходить входження шаблону довжиною
m усередині тексту довжиною n,
пересуваючи вікно розміром m уздовж тексту та
порівнюючи числовий відбиток — хеш — вікна з хешем
шаблону, замість того щоб порівнювати символи безпосередньо
на кожній позиції.
Поліноміальний ковзний хеш
Кожне вікно символів c₀ c₁ … c(m−1) розглядається
як цифри числа в системі числення з основою b:
h = (c₀·b^(m−1) + c₁·b^(m−2) + … + c(m−1)) mod pb— основа (наприклад, 256),p— велике просте число (наприклад, 1 000 000 007), яке обмежує хеш і зменшує кількість колізій.
Зсув за O(1)
Перерахунок хешу з нуля на кожній позиції коштував би
O(m) на зсув. Натомість Рабін–Карп оновлює його
інкрементально: видаляє внесок символу, що виходить із вікна,
зсуває решту цифр на одну позицію та додає символ, що входить —
h′ = ((h − text[i]·b^(m−1))·b + text[i+m]) mod p,
додаючи p перед фінальним mod щоразу, коли
віднімання дає від'ємне число. Це коштує O(1) на
зсув незалежно від m.
Чому потрібна перевірка після збігу хешів
Різні вікна іноді можуть збігатися за значенням хешу, навіть якщо їхні символи відрізняються — хибне спрацювання. Щоразу, коли хеш вікна дорівнює хешу шаблону, Рабін–Карп виконує явне посимвольне порівняння, щоб підтвердити справжній збіг перед його повідомленням, гарантуючи коректність незалежно від колізій.
Складність
Середній і типовий час роботи становить O(n + m),
оскільки перевірка запускається лише при (рідкісних) збігах
хешів. Найгірший випадок — O(n·m), якщо багато
хибних спрацювань змушують виконувати повторні повні
перевірки — вкрай малоймовірно з великим простим модулем, але
це можна продемонструвати тут за допомогою опції малого
модуля. Ідея хешування Рабіна–Карпа також природно
узагальнюється на пошук кількох шаблонів одночасно за
один прохід, чого однопатернові алгоритми не можуть зробити
так само дешево.