Algoritmalar

Rabin-Karp

Dizeler O(n + m) avg O(1)

Deseni ve her metin penceresini yuvarlanan bir hash ile hashler; yalnızca hash'ler çakıştığında karakter karakter doğrular.

text
G0
E1
E2
K3
S4
F5
O6
R7
G8
E9
E10
K11
S12
pattern
G0
E1
E2
K3
patHash=22052winHash=22052
1/31

Desen özeti ve ilk pencerenin özeti ön hesaplanıyor.

DeğişmezPencere özeti, o m karakterin özetine eşittir. Eşit özetler yine farklı olabilir, bu yüzden isabet doğrulanır; farklı özetler asla eşleşemez, bu yüzden ıskalama bedavaya gelir.

rabin-karp.c
#define BASE 256
#define MOD 1000000007
void rabinKarp(const char *t, const char *p) {
int n = strlen(t), m = strlen(p);
long ph = 0, th = 0, pow = 1;
for (int i = 0; i < m; i++) {
ph = (ph * BASE + p[i]) % MOD;
th = (th * BASE + t[i]) % MOD;
if (i) pow = (pow * BASE) % MOD;
}
for (int i = 0; i + m <= n; i++) {
if (ph == th) {
int k = 0;
while (k < m && t[i + k] == p[k]) k++;
if (k == m) printf("found at %d\n", i);
}
if (i + m < n) {
th = ((th - t[i] * pow) * BASE
+ t[i + m]) % MOD;
if (th < 0) th += MOD;
}
}
}

Rabin-Karp nasıl çalışır?

Dizeleri değil hash'leri karşılaştır: yuvarlanan hash, pencere kayarken değerini O(1)'de günceller. Yalnızca hash çakışması gerçek karakter karşılaştırması tetikler.

En iyi durum

Az çakışma: beklenen O(n + m).

En kötü durum

Düşmanca çakışmalar: O(n·m).

Ne zaman kullanılır?

Çoklu desen arama (tek hash kümesi, çok desen), intihal parça eşleme.