COMPUTER ENGINEER

← BlogDATA STRUCTURES / ALGORITHMSPython örnek paketi ↓

Metin algoritmaları · 39 / 53

KMP, prefix function ve Z algoritması

Anla → iz sür → uygula → gerekçelendir

1 dk okuma · uygulama için ayrıca zaman ayır

Naif pattern search mismatch'te yeniden çok harf karşılaştırabilir. KMP, pattern'ın prefix function'ını kullanır: pi[i], pattern[0:i+1]'in kendisi olmayan en uzun prefix=suffix uzunluğudur. Mismatch'te j=pi[j−1] ile daha kısa uygun prefix'e döner; metin indeksini geri almaz.

“aba” için pi=[0,0,1]. Match tamamlanınca overlapping sonuçları bulmak için j tekrar pi[j−1] olur. Z[i] string'in i konumundan başlayan suffix'i ile prefix'inin ortak uzunluğudur; bir [l,r) eşleşme kutusunu kullanarak doğrusal hesaplanır. Pattern+separator+text yaklaşımında separator girdide bulunmamalı veya token seviyesinde özel sentinel seçilmelidir.

Unicode normalization yapılmamış iki görünüşte aynı metin farklı code point dizileri olabilir. Bu algoritmalar verilen sembol dizisini eşler, linguistik anlamı çözmez. Boş pattern davranışı ve sonuç indekslerinin byte/code point olması açıkça belirlenmelidir.

Adım adım iz sürme

Text ababa, pattern aba: matches0 ve2. İlk match sonrası j=1 ile ortak a tutulur; baştan tarama gerekmez.

Maliyet ve varsayımlar

KMP O(n+m) zaman, O(m) alan; çıktı sayısı z ayrıca eklenir.

Çalıştırılabilir örnek

Python 3 ile çalıştır. Assert küçük bir örneği denetler; genel doğruluk ispatı değildir. Bazı ileri örnekler özellikle küçük model veya referans oracle'dır; tam üretim uygulaması değildir.

Python 3
def kmp(text, pattern):
    if not pattern: return list(range(len(text)+1))
    pi=[0]*len(pattern); j=0
    for i in range(1,len(pattern)):
        while j and pattern[i] != pattern[j]: j=pi[j-1]
        if pattern[i] == pattern[j]: j+=1
        pi[i]=j
    out=[]; j=0
    for i,c in enumerate(text):
        while j and c != pattern[j]: j=pi[j-1]
        if c == pattern[j]: j+=1
        if j == len(pattern): out.append(i-j+1); j=pi[j-1]
    return out
assert kmp("ababa","aba") == [0,2]

KAVRADIĞINI KONTROL ET

Sıra sende

Her mismatch'te text indeksini geri almak zorunlu mu?

Çözümün mantığını göster

Hayır. Pattern prefix bilgisini değiştirir; text ileri gider. Doğrusal sınır bu monotonic text ilerlemesine dayanır.

Bir adım ileri

  1. Örneği değiştirmeden önce girdi sözleşmesini ve invariantı yaz.
  2. Uygun olan boş, sınır, tekrar ve adversarial girdileri ekle. Basit bir oracle ile karşılaştır.
  3. Belirtilen modelde maliyeti çıkar; farklı girdi büyüklüklerini ölç ve farkları gerekçelendir.

Temel kaynaklar ve ders notları

Bu eğitimde özgün anlatım kullanıldı; aşağıdaki kaynaklar ispatlar ve ileri okumalar sunar. Bağlantılar daha geniş ders modülünü kapsayabilir.

Princeton · Algorithms, Sedgewick & Wayne ↗
İlerlemeden önce alıştırmayı çöz.