Algoritmalar

Boyer-Moore

Dizeler O(n/m) best O(σ)

Deseni sağdan sola karşılaştırır ve kötü-karakter tablosuyla umutsuz hizalamaların üzerinden atlar — pratikte çoğu zaman alt-doğrusal.

pattern
A00
B·1
C·2
i=0
1/45

last['A'] = 0 — şimdiye kadarki en sağdaki geçiş.

DeğişmezSağdan sola karşılaştırmak, desende hiç bulunmayan bir uyuşmaz karakterin tüm desenin onun ötesine atlamasına izin verir.

boyer-moore.c
#define R 256
void badChar(const char *p, int m, int last[R]) {
for (int c = 0; c < R; c++) last[c] = -1;
for (int i = 0; i < m; i++)
last[(int)p[i]] = i;
}
void boyerMoore(const char *t, const char *p) {
int n = strlen(t), m = strlen(p);
int last[R];
badChar(p, m, last);
int s = 0;
while (s <= n - m) {
int j = m - 1;
while (j >= 0 && p[j] == t[s + j])
j--;
if (j < 0) {
printf("found at %d\n", s);
s += 1;
} else {
int shift = j - last[(int)t[s + j]];
s += shift > 1 ? shift : 1;
}
}
}

Boyer-Moore nasıl çalışır?

Deseni sağdan sola karşılaştır. Uyumsuzlukta kötü-karakter kuralı deseni, sorunlu metin karakterinin desendeki son geçtiği yer hizalanacak şekilde kaydırır — çoğu zaman tek sıçrayışta çok konum atlanır.

En iyi durum

Zengin alfabeli metin: yaklaşık n/m karakter bakışı — alt-doğrusal.

En kötü durum

Yozlaşmış tekrarlı girdiler: yalnız kötü-karakterli türev için O(n·m).

Ne zaman kullanılır?

Büyük alfabede uzun desenler: editörlerin 'bul'u, grep tarzı tarama.