Bölüm 5: Dizgi Algoritmaları
Çıktı Sorusu · Kaba Kuvvet
Soru 1: Kaç Karşılaştırma?
Dersteki kabaKuvvet metodu kabaKuvvet("abracacadabra", "cad") çağrısında hangi değeri döndürür ve toplam kaç karakter karşılaştırması yapar?
int kabaKuvvet(String t, String p) { int n = t.length(), m = p.length(); for (int i = 0; i <= n - m; i++) { int j = 0; while (j < m && t.charAt(i + j) == p.charAt(j)) j++; if (j == m) return i; } return -1; }
Cevabı göster
Dönüş: 6 · karşılaştırma: 11
- s = 0, 1, 2, 3: ilk karakter (a, b, r, a) ≠ c → 4 × 1 = 4
- s = 4: c = c, a = a, c ≠ d → 3
- s = 5: a ≠ c → 1
- s = 6: c, a, d eşleşir → 3; j == m olduğu için 6 döner
4 + 3 + 1 + 3 = 11. Uyuşmazlıkta öğrenilen bilgi atılır; örüntü her seferinde yalnızca 1 kayar.
Çoktan Seçmeli · Kaba Kuvvet
Soru 2: En Kötü Durum
Metin 15 tane adan oluşuyor ("aaa…a", n = 15), örüntü "aaaab". Kaba kuvvet toplam kaç karakter karşılaştırması yapar?
B: Geçerli kaymalar 0..n − m, yani 15 − 5 + 1 = 11 hizadır; her hizada dört a eşleşir ve uyuşmazlık son karakterde çıkar → 11 · 5 = 55. 75, n · m üst sınırıdır; 50, son hizanın (s = 10) unutulduğu sayımdır; 11 yalnızca hiza sayısıdır.
Çoktan Seçmeli · Kaba Kuvvet
Soru 3: Döngü Sınırı Hatası
kabaKuvvet metodundaki i <= n - m koşulu yanlışlıkla i < n - m yazılırsa aşağıdaki çağrılardan hangisi yanlış sonuç (−1) döndürür?
C: n = 5, m = 2 için doğru kaymalar 0..3'tür; hatalı koşul yalnızca 0, 1, 2'yi dener. "em" yalnızca s = 3 = n − m konumunda geçtiği için bulunamaz. "le" s = 2'de olduğu için hâlâ bulunur.
Adım Adım Çalıştırma · Kaba Kuvvet
Soru 4: kabaKuvvet İzleme
kabaKuvvet("AABAABAAC", "AAC") hangi değeri döndürür, kaç karakter karşılaştırması yapılır?
n = 9, m = 3: geçerli kaymalar i = 0..6. Örüntü metnin altına i = 0 hizasında yerleşecek.
i = 0: 2 karakter eşleşti, t[2] = 'B' ≠ p[2] = 'C' → örüntü 1 kayar.
i = 1: 1 karakter eşleşti, t[2] = 'B' ≠ p[1] = 'A' → örüntü 1 kayar.
i = 2: t[2] = 'B' ≠ p[0] = 'A' → ilk karakterde uyuşmazlık, örüntü 1 kayar.
i = 3: 2 karakter eşleşti, t[5] = 'B' ≠ p[2] = 'C' → örüntü 1 kayar.
i = 4: 1 karakter eşleşti, t[5] = 'B' ≠ p[1] = 'A' → örüntü 1 kayar.
i = 5: t[5] = 'B' ≠ p[0] = 'A' → ilk karakterde uyuşmazlık, örüntü 1 kayar.
i = 6: A, A, C üçü de eşleşti; j = 3 = m olunca while döngüsü biter.
j == m → 6 döndürülür. Toplam 15 karşılaştırma; aynı A'lar farklı hizalarda tekrar tekrar okundu.
int kabaKuvvet(String t, String p) { int n = t.length(), m = p.length(); for (int i = 0; i <= n - m; i++) { int j = 0; while (j < m && t.charAt(i + j) == p.charAt(j)) j++; if (j == m) return i; } return -1; }
Çoktan Seçmeli · KMP
Soru 5: LPS Tanımı
lpsHesapla("aaaa") hangi diziyi döndürür?
A: lps[q], P[0..q]'nun kendisine eşit olmayan (uygun) ve aynı zamanda soneki olan en uzun önekidir. "aaaa" için bu "aaa" → 3. B dizginin kendisini de sayar; D ise yalnızca tek karakterlik öneki dener.
Çıktı Sorusu · KMP
Soru 6: LPS Tablosu
"AABAACAABAA" örüntüsünün LPS tablosunu (önek fonksiyonu) bulun. q = 5 ve q = 10 için gerekçeyi yazın.
Cevabı göster
lps = [0, 1, 0, 1, 2, 0, 1, 2, 3, 4, 5]
- q = 5 (C): "AABAAC"; C ile biten bir önek yok (önekler A ile başlayıp A, AA, AAB… diye gider) → 0.
- q = 10: "AABAACAABAA"nın sonu "AABAA" ile, başı da "AABAA" ile aynı → 5.
- q = 6..10: "AABAA" öneki yeniden başladığından değerler 1, 2, 3, 4, 5 diye artar.
Adım Adım Çalıştırma · KMP
Soru 7: lpsHesapla İzleme
lpsHesapla("ababaca") hangi diziyi döndürür?
lps[0] = 0 her zaman (tek karakterin uygun öneki yok). k: o ana kadar eşleşen önek uzunluğu.
p[0] = 'a' ≠ p[1] = 'b' → k = 0 kalır, lps[1] = 0.
p[0] = 'a' = p[2] → k = 1, lps[2] = 1.
p[1] = 'b' = p[3] → k = 2, lps[3] = 2.
p[2] = 'a' = p[4] → k = 3, lps[4] = 3.
p[3] = 'b' ≠ p[5] = 'c' → geri çekil: k = lps[2] = 1.
p[1] = 'b' ≠ p[5] = 'c' → geri çekil: k = lps[0] = 0.
p[0] = 'a' ≠ p[5] = 'c' → k = 0 kalır, lps[5] = 0.
p[0] = 'a' = p[6] → k = 1, lps[6] = 1.
Sonuç: lps = [0, 0, 1, 2, 3, 0, 1]. Toplam geri çekilme toplam artışı aşamaz → O(m).
int[] lpsHesapla(String p) { int m = p.length(), k = 0; int[] lps = new int[m]; for (int q = 1; q < m; q++) { while (k > 0 && p.charAt(k) != p.charAt(q)) k = lps[k - 1]; if (p.charAt(k) == p.charAt(q)) k++; lps[q] = k; } return lps; }
Çoktan Seçmeli · KMP
Soru 8: Uyuşmazlıkta Geri Çekilme
Örüntü "abcabd" için lps = [0, 0, 0, 1, 2, 0]. KMP aramasında metinle "abcab" eşleşmişken (q = 5) sıradaki metin karakteri d değil. q hangi değeri alır ve örüntü kaç konum kaymış olur?
D: q = lps[q − 1] = lps[4] = 2, çünkü "ab" eşleşen "abcab"ın hem öneki hem sonekidir; kayma 5 − 2 = 3. B, lps[q] (lps[5] = 0) kullanma hatasıdır. Metin işaretçisi i geri gitmez; "ab" yeniden karşılaştırılmaz.
Çıktı Sorusu · KMP
Soru 9: Üç Algoritma, Bir Metin
Metin "gel de geleyim", örüntü "geleyim". Kaba kuvvet, KMP ve Boyer-Moore (yalnızca kötü karakter kuralı) ilk eşleşmeyi bulana kadar kaçar karakter karşılaştırması yapar? Eşleşme hangi konumdadır?
Cevabı göster
Eşleşme s = 7. Karşılaştırmalar: kaba kuvvet 17, KMP 15, Boyer-Moore 8.
- Kaba kuvvet: s = 0'da "gel" eşleşir, '␣' ≠ 'e' (4); s = 1..6 ilk karakterde biter (6); s = 7'de 7 → 17.
- KMP (lps hep 0): "gel" (3), '␣' önce p[3] sonra p[0] ile (2), d, e, ␣ (3), geleyim (7) → 15. Metin hiç geri okunmaz.
- Boyer-Moore: s = 0'da sağdan ilk karşılaştırma t[6] = '␣' ≠ 'm'; ␣ örüntüde yok → 7 kaydır; s = 7'de 7 eşleşme → 8.
Çoktan Seçmeli · KMP
Soru 10: KMP Neden Doğrusal?
KMP aramasında while döngüsündeki geri çekilmelerin (q = lps[q - 1]) toplam sayısı neden n'yi aşamaz?
B: Amortize argüman: q her adımda en çok 1 artar (toplam ≤ n), her geri çekilme onu en az 1 azaltır ve q ≥ 0 kalır; bu yüzden toplam geri çekilme ≤ n, arama O(n). C yanlıştır: KMP'de i hiç geri gitmez; A da yanlıştır: lps değerleri m − 1'e kadar çıkabilir.
Adım Adım Çalıştırma · KMP
Soru 11: kmpAra İzleme
kmpAra("abababca", "ababc") hangi değeri döndürür?
n = 8, m = 5, lps("ababc") = [0, 0, 1, 2, 0]. q: örüntünün metinle eşleşmiş önek uzunluğu.
p[0] = t[0] = 'a' → q = 1.
p[1] = t[1] = 'b' → q = 2.
p[2] = t[2] = 'a' → q = 3.
p[3] = t[3] = 'b' → q = 4.
p[4] = 'c' ≠ t[4] = 'a' → q = lps[3] = 2; i yerinde kalır, örüntü 2 kayar.
p[2] = t[4] = 'a' → q = 3.
p[3] = t[5] = 'b' → q = 4.
p[4] = t[6] = 'c' → q = 5 = m: 2 döndürülür (i − m + 1). Metin bir kez tarandı.
int kmpAra(String t, String p) { int n = t.length(), m = p.length(); int[] lps = lpsHesapla(p); int q = 0; // eşleşen uzunluk for (int i = 0; i < n; i++) { while (q > 0 && p.charAt(q) != t.charAt(i)) q = lps[q - 1]; if (p.charAt(q) == t.charAt(i)) q++; if (q == m) return i - m + 1; } return -1; }
Çıktı Sorusu · Boyer-Moore
Soru 12: Son Görülme ve Hizalar
"TRUSTHARDTOOTHBRUSHES" metninde "TOOTH" Boyer-Moore ile (yalnızca kötü karakter kuralı, s += max(1, j − son[c])) aranıyor. Son görülme tablosunu yazın; örüntü hangi hizalarda denenir ve toplam kaç karşılaştırma yapılır?
Cevabı göster
son: T = 3, O = 2, H = 4, diğer = −1.
| s | uyuşmazlık | kaydırma |
|---|---|---|
| 0 | t[4] = T ≠ H (j = 4) | 4 − 3 = 1 |
| 1 | H, T eşleşti; t[3] = S ≠ O (j = 2) | 2 − (−1) = 3 |
| 4 | t[8] = D ≠ H (j = 4) | 4 − (−1) = 5 |
| 9 | 5 karakter eşleşti | bulundu |
4 hiza, 1 + 3 + 1 + 5 = 10 karşılaştırma; eşleşme s = 9.
Çoktan Seçmeli · Boyer-Moore
Soru 13: max(1, …) Neden Var?
Boyer-Moore'da kaydırma s += Math.max(1, j - son[c]) yerine s += j - son[c] yazılırsa ne olur?
A: Örneğin "abacab"da c = a için son = 4'tür; uyuşmazlık j = 3'te çıkarsa 3 − 4 = −1 olur. max(1, …) en az 1 ilerlemeyi garanti eder; yoksa sonsuz döngü ya da geri gitme olur. B yanlıştır: j + 1 kaydırma güvenlidir, çünkü c'yi içeren hiçbir hiza eşleşemez.
Adım Adım Çalıştırma · Boyer-Moore
Soru 14: boyerMoore İzleme
boyerMoore("KARTAL KALKAR", "KALKAR") hangi değeri döndürür?
n = 13, m = 6. Son görülme: K = 3, A = 4, L = 2, R = 5, diğerleri −1. Karşılaştırma sağdan sola yapılacak.
s = 0: p[5] = 'R' ≠ t[5] = 'L'. Kötü karakter: 'L'.
son['L'] = 2 → max(1, 5 − 2) = 3; s = 3.
s = 3: p[5] = 'R' ≠ t[8] = 'A'. Kötü karakter: 'A'.
son['A'] = 4 → max(1, 5 − 4) = 1; s = 4.
s = 4: p[5] = 'R' ≠ t[9] = 'L'. Kötü karakter: 'L'.
son['L'] = 2 → max(1, 5 − 2) = 3; s = 7.
s = 7: R, A, K, L, A, K sağdan sola eşleşti, j = −1.
j < 0 → 7 döndürülür. 4 hiza, toplam 9 karşılaştırma (kaba kuvvet 8 hiza dener).
int boyerMoore(String t, String p) { int n = t.length(), m = p.length(); int[] son = sonGorulme(p); int s = 0; while (s <= n - m) { int j = m - 1; while (j >= 0 && p.charAt(j) == t.charAt(s + j)) j--; if (j < 0) return s; s += Math.max(1, j - son[t.charAt(s + j)]); } return -1; }
Çıktı Sorusu · Boyer-Moore
Soru 15: Horspool Kaydırma Tablosu
"BARBER" örüntüsü için Horspool kaydırma tablosunu kayd[c] = m − 1 − (c'nin P[0..m−2] içindeki en sağ konumu), yoksa m kuralıyla kurun. Hizanın son karakterinin altındaki metin karakteri B, R ve X olursa örüntü kaçar kaydırılır?
Cevabı göster
m = 6; tabloya yalnızca P[0..4] = B A R B E katılır:
| c | B | A | R | E | diğer |
|---|---|---|---|---|---|
| kayd[c] | 5 − 3 = 2 | 5 − 1 = 4 | 5 − 2 = 3 | 5 − 4 = 1 | 6 |
B → 2, R → 3, X → 6. Son karakter (R, indis 5) tabloya katılmaz; R yine de indis 2'de geçtiği için 3 kaydırır. Kaydırma, uyuşmazlığın nerede olduğuna bakmaz; hep hizanın son karakterine göre yapılır.
Çoktan Seçmeli · Boyer-Moore
Soru 16: En İyi Durum
n = 1000 karakterlik metnin hiçbir karakteri, m = 10 uzunluklu örüntüde geçmiyor. Boyer-Moore (kötü karakter kuralı) toplam kaç karakter karşılaştırması yapar?
C: Her hizada sağdan ilk karşılaştırma uyuşmaz; c örüntüde olmadığından j − (−1) = 10 kaydırılır. Hizalar s = 0, 10, …, 990 → 100 hiza × 1 = 100 ≈ n/m. 991, kaba kuvvetin en iyi durumudur (her hizada 1 karşılaştırma, kayma 1).
Çıktı Sorusu · Rabin-Karp
Soru 17: Kayan Hash
Taban B = 10, Q = 11, karakterler rakam; T = "26535", m = 3. h("265") = 265 mod 11 = 1 ve Bm−1 mod Q = 100 mod 11 = 1'dir. Kaydırma formülü hs+1 = (B · (hs − t[s] · Bm−1) + t[s+m]) mod Q ile h("653") ve h("535")'i bulun.
Cevabı göster
- h("653") = (10 · (1 − 2 · 1) + 3) mod 11 = (−7) mod 11 = 4 ✓ (653 = 59 · 11 + 4)
- h("535") = (10 · (4 − 6 · 1) + 5) mod 11 = (−15) mod 11 = 7 ✓ (535 = 48 · 11 + 7)
Her yeni pencere O(1)'de: çıkan rakam düşülür, kalanlar bir basamak sola kayar, giren rakam eklenir. Ara sonuç negatif çıkabilir; Java'da % negatif verdiği için if (th < 0) th += Q gerekir.
Çoktan Seçmeli · Rabin-Karp
Soru 18: Sahte Eşleşme
Oyuncak hash: harf değerlerinin toplamı (a = 1, b = 2, c = 3, d = 4). "adcb" metninde "bc" (hash 5) aranıyor. Hangi pencereler sahte eşleşme (spurious hit) olur?
D: Pencereler "ad" = 5, "dc" = 7, "cb" = 5. İki pencerenin hash'i örüntününkine eşittir ama karakterleri farklıdır; doğrulama ikisini de reddeder ve metinde "bc" yoktur. Toplam hash sıraya duyarsızdır ("cb" de 5 verir); bu yüzden konum ağırlıklı polinom hash kullanılır.
Adım Adım Çalıştırma · Rabin-Karp
Soru 19: rabinKarp İzleme
rabinKarp("alakart", "kar") hangi değeri döndürür; kaç pencerede karakter doğrulaması yapılır?
B = 256, Q = 101. Örüntü "kar" 3 karakterlik pencerelerle karşılaştırılacak; n − m + 1 = 5 pencere var.
h = 256² mod 101 = 88: pencereden çıkan karakterin ağırlığı.
ph = hash("kar") = 22; ilk pencere "ala" için th = 22.
s = 0: th = ph = 22 ama esit("ala", "kar") yanlış → sahte eşleşme; 3 karakter boşa karşılaştırıldı.
Kaydır: 'a' çıkar, 'k' girer → th = 2.
s = 1: th = 2 ≠ 22, karakterlere bakılmaz. Kaydır: 'l' çıkar, 'a' girer → th = 69.
s = 2: th = 69 ≠ 22, geç. Kaydır: 'a' çıkar, 'r' girer → th = 22.
s = 3: th = ph = 22 ve esit("kar", "kar") doğru → 3 döndürülür. 2 doğrulamadan biri boşa gitti.
int rabinKarp(String t, String p) { int n = t.length(), m = p.length(); int B = 256, Q = 101, h = 1, ph = 0, th = 0; for (int i = 0; i < m - 1; i++) h = (h * B) % Q; for (int i = 0; i < m; i++) { ph = (B * ph + p.charAt(i)) % Q; th = (B * th + t.charAt(i)) % Q; } for (int s = 0; s <= n - m; s++) { if (ph == th && esit(t, p, s)) return s; if (s < n - m) { th = (B * (th - t.charAt(s) * h) + t.charAt(s + m)) % Q; if (th < 0) th += Q; } } return -1; }
Çoktan Seçmeli · Rabin-Karp
Soru 20: Hash Karşılaştırmasının Sakıncası
"abracadabra" içinde "cad" aranırken Rabin-Karp örüntünün ve her pencerenin hash değerini karşılaştırıyor. Yalnızca hash değerlerini karşılaştırmanın temel sakıncası nedir?
A: Hash çakışması (sahte eşleşme) olabilir; hash eşitliği eşleşmeyi garanti etmez, bu yüzden karakter karakter doğrulama yapılır. Büyük asal Q çakışma olasılığını ≈ 1/Q'ya indirir; çok sayıda çakışmada süre O(n · m)'ye çıkar. Eşit dizgilerin hash'i her zaman eşittir (D yanlış).
Çoktan Seçmeli · Rabin-Karp
Soru 21: Çok Sayıda Örüntü
Aynı uzunlukta 500 farklı virüs imzası bir dosyada tek geçişte aranacak. Hangi yaklaşım en uygundur?
B: Pencere hash'i O(1)'de güncellenir ve HashSet'te O(1) ortalamayla aranır; bulunursa doğrulanır → beklenen O(n + k · m). A ve D dosyayı k kez tarar; C ise imzaları birleştirince hiçbir imzayı tek başına bulmaz.
Çıktı Sorusu · RLE
Soru 22: rleSikistir Çıktısı
Dersteki rleSikistir metoduyla aşağıdaki kod ne yazdırır? Her satır için sıkıştırma oranını (sıkıştırılmış / orijinal) hesaplayın.
System.out.println(rleSikistir("aaabccddddde"));
System.out.println(rleSikistir("abc"));
System.out.println(rleSikistir("zzzzzzzzzzzz"));Cevabı göster
3a1b2c5d1e 1a1b1c 12z
- 12 → 10 karakter: oran 10/12 ≈ 0,83
- 3 → 6 karakter: oran 2; tekrar yoksa RLE büyütür.
- 12 → 3 karakter: oran 0,25; sayı iki basamaklıdır, açıcı rakamları biriktirerek okumalıdır (
sayi = sayi · 10 + rakam).
Çoktan Seçmeli · RLE
Soru 23: RLE Ne Zaman Büyütür?
rleSikistir aşağıdaki girdilerden hangisinin çıktısını girdiden uzun yapar?
D: Hiç ardışık tekrar yok; her karakter "1" + karakter olarak yazılır: 8 → 16 karakter (iki kat). Diğerleri küçülür: "5a5b" (10 → 4), "4a1b4a" (9 → 6), "11x1y" (12 → 5). RLE yalnızca ardışık tekrarı yakalar; "abab…" gibi tekrar eden dizgileri LZW yakalar.
Adım Adım Çalıştırma · RLE
Soru 24: rleSikistir İzleme
rleSikistir("aaabccdddd") hangi dizgiyi döndürür?
n = 10, sonuc boş. Her koşu (ardışık aynı karakterler) sayı + karakter olarak yazılacak.
Yeni koşu: c = 'a', sayac = 1 (i = 0).
while 2 kez döndü: sayac = 3, i = 2. "3a" eklenir.
Yeni koşu: c = 'b', sayac = 1 (i = 3).
s[4] = 'c' ≠ 'b': while hiç dönmez. "1b" eklenir.
Yeni koşu: c = 'c', sayac = 1 (i = 4).
while 1 kez döndü: sayac = 2, i = 5. "2c" eklenir.
Yeni koşu: c = 'd', sayac = 1 (i = 6).
while 3 kez döndü: sayac = 4, i = 9. "4d" eklenir.
Sonuç: "3a1b2c4d" (10 → 8 karakter). İç while i'yi de ilerlettiği için toplam iş O(n).
String rleSikistir(String s) {
StringBuilder sonuc = new StringBuilder();
int n = s.length();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
int sayac = 1;
while (i + 1 < n &&
s.charAt(i + 1) == c) {
sayac++;
i++;
}
sonuc.append(sayac).append(c);
}
return sonuc.toString();
}Adım Adım Çalıştırma · LZW
Soru 25: lzw İzleme
Başlangıç sözlüğü A = 0, B = 1 iken lzw("BABAABAAA") hangi kodları üretir?
Sözlük tek karakterlerle başlar: A = 0, B = 1; yeni dizgiler 2'den numaralanır. w = "".
"B" sözlükte (1) → w = "B"; daha uzun eşleşme aranır.
"BA" yok → w = "B" kodu 1 çıktıya; "BA" = 2 eklenir; w = "A".
"AB" yok → w = "A" kodu 0 çıktıya; "AB" = 3 eklenir; w = "B".
"BA" sözlükte (2) → w = "BA"; daha uzun eşleşme aranır.
"BAA" yok → w = "BA" kodu 2 çıktıya; "BAA" = 4 eklenir; w = "A".
"AB" sözlükte (3) → w = "AB"; daha uzun eşleşme aranır.
"ABA" yok → w = "AB" kodu 3 çıktıya; "ABA" = 5 eklenir; w = "A".
"AA" yok → w = "A" kodu 0 çıktıya; "AA" = 6 eklenir; w = "A".
"AA" sözlükte (6) → w = "AA"; daha uzun eşleşme aranır.
Döngü bitti; kalan w = "AA" kodu 6 eklenir. Çıktı: 1 0 2 3 0 6 (9 sembol → 6 kod).
List<Integer> lzw(String s) {
Map<String, Integer> sozluk = ilkSozluk(s);
String w = "";
List<Integer> kod = new ArrayList<>();
for (char c : s.toCharArray()) {
String wc = w + c;
if (sozluk.containsKey(wc)) {
w = wc;
} else {
kod.add(sozluk.get(w));
sozluk.put(wc, sozluk.size());
w = "" + c;
}
}
if (!w.isEmpty()) kod.add(sozluk.get(w));
return kod;
}Çıktı Sorusu · LZW
Soru 26: LZW Açma
Başlangıç sözlüğü A = 0, B = 1, C = 2. LZW ile sıkıştırılmış 0 1 3 2 4 7 kod dizisini açın. Hangi kodda açıcı "henüz tanımlanmamış kod" durumuyla karşılaşır?
Cevabı göster
| kod | yazılan | sözlüğe eklenen |
|---|---|---|
| 0 | A | — |
| 1 | B | 3 = AB |
| 3 | AB | 4 = BA |
| 2 | C | 5 = ABC |
| 4 | BA | 6 = CB |
| 7 | BAB | 7 = BAB (özel durum) |
Sonuç: ABABCBABAB. 7 okunduğunda açıcının sözlüğü 6'ya kadardır: e = w + w[0] = "BA" + "B" = "BAB". Kontrol: lzw("ABABCBABAB") yine 0 1 3 2 4 7 verir.
Çoktan Seçmeli · LZW
Soru 27: LZ78 Çıktısı
Sözlüğü boş başlayan LZ78, "abababa" dizgisini hangi (indis, karakter) çiftlerine dönüştürür?
C: a → (0, a), 1 = a · b → (0, b), 2 = b · "ab": a var (1), ab yok → (1, b), 3 = ab · "aba": ab var (3) → (3, a), 4 = aba. LZW'nin farkı sözlüğü tüm tek karakterlerle başlatmasıdır; böylece çıktıda karakter yazmaya gerek kalmaz.
Çoktan Seçmeli · LZW
Soru 28: RLE mi, LZW mi?
Aşağıdaki 18 karakterlik girdilerden hangisinde RLE girdiyi büyütürken LZW (a, b, c ile başlayan sözlük) kod sayısını yarıya indirir?
B: Ardışık tekrar yok; RLE "1a1b1c…" ile 36 karaktere çıkar. LZW tekrar eden "abc" parçalarını sözlüğe ekler ve 9 kod üretir (0 1 2 3 5 4 6 9 4). A, C ve D'de uzun koşular vardır; onlarda RLE çok etkilidir.
Klasik Soru · Karşılaştırma
Soru 29: Senaryoya Göre Algoritma
Her senaryo için dersteki dizgi eşleştirme algoritmalarından birini seçin ve gerekçesini yazın:
(a) Ağdan akan ve geri okunamayan veride, en kötü durumu sınırlı bir arama gerekiyor.
(b) Bir editörde uzun bir İngilizce metinde 12 harfli bir kelime aranıyor.
(c) Bir belgede aynı uzunlukta binlerce cümle (intihal kontrolü) aranıyor.
Cevabı göster
- (a) KMP: metin işaretçisi asla geri gitmez (akışa uygun); en kötü durumda da O(n + m).
- (b) Boyer-Moore / Horspool: uzun örüntü ve geniş alfabede kötü karakter kuralı neredeyse m karakter atlar; pratikte en hızlısı, en iyi O(n/m).
- (c) Rabin-Karp: örüntü hash'leri bir kümeye konur, her pencere O(1)'de güncellenip kümede aranır; beklenen O(n + k · m).
Kaba kuvvet ön işleme istemez ve kısa örüntüde yeterlidir, ama en kötü durumu O(n · m)'dir.
Klasik Soru · Karşılaştırma
Soru 30: LZW Özel Durumu
A = 0, B = 1 sözlüğüyle "ABABABA" sıkıştırılınca çıktı 0 1 2 4 olur. Açıcı 4 kodunu okuduğunda bu kod sözlüğünde henüz yoktur. Neden böyle olur ve açıcı 4'ün karşılığını nasıl bulur?
Cevabı göster
| kod | yazılan | eklenen |
|---|---|---|
| 0 | A | — |
| 1 | B | 2 = AB |
| 2 | AB | 3 = BA |
| 4 | ABA | 4 = ABA |
Açıcı sözlüğe bir adım geriden ekler: bir girdiyi ancak sonraki kodun ilk karakterini öğrenince tamamlar. Sıkıştırıcı 4 = "ABA"yı ekleyip hemen ardından kullandığında (cScSc kalıbı) açıcıda 4 henüz yoktur.
Bu durumda yazılacak dizgi w ile başlar ve ilk karakteri w[0]'dır: e = w + w[0] = "AB" + "A" = "ABA". Sonuç: A · B · AB · ABA = ABABABA ✓.