İlginç olan şu ki, Bir metin içinde desen aramak ilk bakışta basit görünüyor. Gerçekten öyle. Ama işin içine uzun log dosyaları, devasa kullanıcı yorumları ya da milyonlarca satırlık bir kod tabanı girince — o masum “bul” işlemi bir anda can sıkıcı bir yük haline geliyor, hem de fark etmeden. İşte KMP tam burada sahneye çıkıyor; hani şu klasik yöntemlerin her uyuşmazlıkta başa dönüp aynı karakterleri defalarca kontrol ettiği anlarda, biraz daha akıllı davranan, biraz daha tutumlu olan yaklaşım.
Ben bu algoritmayı ilk kez 2018’in sonlarında, İstanbul’da bir log analiz aracını kurcalarken ciddiye almıştım. O zamanlar küçük bir startup’taydım; ekipte üç geliştirici vardık. Yanlış eşleşmeler yüzünden tarama süreleri uzayıp gidiyordu. Açık konuşayım, KMP’yi ilk gördüğümde içimden “bu niye bu kadar uğraştırıyor?” dedim. Ciddi dedim. Ama lps mantığını elle test edince taşlar yerli yerine oturdu. Aslında — dur bir saniye, önce şunu söyleyeyim: algoritmanın olayı hızdan çok israfı kesmek. Bu fark küçük görünüyor ama değil.
KMP Neden Bu Kadar Önemli?
Naif arama yöntemiyle kıyasladığınızda fark hemen gözünüze çarpıyor. Diyelim ki metnin içinde “ababac” gibi tekrar eden parçalar var ve siz “ababc” desenini arıyorsunuz — her uyuşmazlıkta en başa dönmek kulağa temiz geliyor, düzenli bile, ama pratikte bayağı pahalıya patlıyor (yanlış duymadınız). KMP ise desenin kendi iç yapısını okuyup nerede geri saracağını zaten önceden biliyor.
İşin aslı şu ki, KMP’nin zekâsı metinden değil desenden geliyor. Önce pattern için bir özet çıkarıyor; sonra arama sırasında bu özeti kullanıp gereksiz karşılaştırmaları çöpe atıyor (ben de ilk duyduğumda şaşırmıştım). Bu yüzden uzun metinlerde çok daha dengeli çalışıyor. Günlük kullanımda fark edilmez gibi duran şeyler, büyük veride ciddi zaman kazandırabiliyor — bunu kendi gözlerimle gördüm.
Şunu fark ettim: Geçen yıl 2024 Mart’ında Ankara’daki bir e-ticaret projesinde buna benzer bir durumla uğraştım. Ürün açıklamalarında belirli kelime kalıplarını tarayan küçük bir servis vardı. Ekibin beklentisi doğrusu pek yüksek değildi; çünkü “arama zaten aramadır” diye düşünülüyordu, kimse sorgulamıyordu. Ama LPS mantığıyla döngü sayısı düşürülünce CPU tarafında gözle görülür bir rahatlama oldu. Tabii mucize değil; veri çok dağınıksa yine sınırlara çarpıyorsunuz, bunu da ekleyeyim.
Şimdi gelelim işin can alıcı noktasına.
KMP’nin en güzel yani, aynı karakterleri yeniden yeniden okumayı bırakmasıdır. Küçük veri setlerinde fark az olabilir ama büyük metinde resmen nefes aldırır.
LPS Dizisi Ne Yapıyor?
LPS dediğimiz şey kısaca “Longest Prefix Suffix”. Yani dizenin başından aldığı parçayla sonundan aldığı parçanın ne kadar örtüştüğünü söylüyor bize. Mesela pattern içinde belli bir noktaya geldiniz ve uyumsuzluk çıktı… KMP size diyor ki: “Durun bakalım, sıfırdan başlamayın; elinizde zaten hazır bilgi var.” Ve haklı.
Şahsen, Bu kavram ilk öğrenildiğinde biraz soyut gelebiliyor, kabul ediyorum. Ben de 2020 yazında Berlin’deki uzaktan çalışan ekiplerden biriyle kod incelemesi yaparken bunu anlatmaya çalışmıştım; beyaz tahta yoktu, sadece ekran paylaşımı vardı ve herkes kahveye abanıyordu — dikkatler dağınıktı yani. En sonunda küçük örneklerle gösterince mesele oturdu: prefix ile suffix’in ortak alanı aslında yeniden kullanılabilir hafıza gibi davranıyor, önceki işi çöpe atmıyorsunuz.
Peki neden? Daha fazla bilgi için Butterfly CSS: 2026’da Dikkat Çeken Hafif Bir Seçenek yazımıza bakabilirsiniz. PDF Dünyasında Bir Nefes: Ücretsiz ve Limitsiz Araçlar yazımızda bu konuya da değinmiştik.
| Aşama | Klasik Arama | KMP |
|---|---|---|
| Uyuşmazlık sonrası davranış | Başa döner | LPS’ye göre devam eder |
| Tekrar kontrol edilen karakterler | Çok olabilir | Daha az olur |
| Büyük metinde performans | Zorlanabilir | Daha stabil çalışır |
| Anlaması / uygulaması | Daha kolay | Daha karmaşık |
Kod Mantığına Yakından Bakalım
Kod tarafında iki ayrı aşama var: önce LPS üretimi, sonra arama süreci. İlki pattern’i hazırlıyor, ikincisi ise text içinde geziniyor. İkisini ayırmak önemli — çünkü çoğu kişi doğrudan search kısmına odaklanıp hazırlık adımını hafife alıyor. Yanlış öncelik.
function constructLps(pat, lps) {
let len = 0;
lps[0] = 0;
let i = 1;
while (i < pat.length) {
if (pat[i] === pat[len]) {
len++;
lps[i] = len;
i++;
} else {
if (len !== 0) {
len = lps[len — 1];
} else {
lps[i] = 0;
i++;
}
}
}
}
Burada kritik nokta şu: uyuşmazlık olduğunda `len` değerini bayağı silmiyorsunuz; onun yerine geçmişten gelen daha kısa eşleşmeye zıplıyorsunuz (ben de ilk duyduğumda şaşırmıştım). Bu da sanki merdivenden tek tek inmek yerine ara basamaklara inmek gibi… Daha az yorucu, daha hesaplı. Siz hiç denediniz mi? Güzel bir detay aslında. ASCII’yi Python ve JavaScript’te Böyle Okuyun: Kolay Rehber yazımızda bu konuya da değinmiştik.
Yani, `search` fonksiyonunda ise iki pointer var: biri text için (`i`), diğeri pattern için (`j`) (yanlış duymadınız). Karakterler eşleşirse ikisi de ilerliyor; eşleşme bozulursa `j`, LPS yardımıyla geriye çekiliyor ya da hiç uygunluk yoksa `i` ilerliyor. Güzellik tam burada yatıyor — boşuna geri sarma yok, emek ziyan gitmiyor. Bu konuyla ilgili Kanser Tedavisinde Sürpriz: Tümör Yiyen Bakteriler yazımıza da göz atmanızı tavsiye ederim.
Nerede İşe Yarıyor, Nerede Zorlanıyor?
Kendi deneyimimden konuşuyorum, Küçük scriptlerde açık konuşayım, naif yöntem çoğu zaman yeterli bile oluyor. Mesela birkaç yüz karakterlik string üzerinde kimse kalkıp KMP implement etmeye üşenmez mi? Üşenir tabi. Ama log analizi, DNA dizileri, güvenlik imzaları ya da doküman içi taramalarda tablo tamamen değişiyor. Daha fazla bilgi için İran, Hürmüz’de Bitcoin ile Geçiş Ücreti Mi Toplayacak? yazımıza bakabilirsiniz.
Bana göre en güçlü senaryo sunucu tarafındaki yoğun taramalar. Bir log platformunda aynı deseni defalarca sorguluyorsanız veya IDS benzeri sistemlerde imza yakalamaya çalışıyorsanız KMP fena değil, hatta bayağı işe yarıyor (bu beni çok şaşırttı). Buna karşın pattern çok kısa. Veri çok azsa fazladan hazırlık maliyeti hissedilebilir; yani her durumda kral değil, bunu bilmek lazım.
- Küçük veri seti: Basit yöntem bazen daha pratik olur.
- Büyük metinler: KMP net kazanım sağlar.
- Sık tekrar eden desenler: LPS sayesinde ciddi tasarruf gelir. — ciddi fark yaratıyor
- Ekip deneyimi düşükse: Kodun okunurluğu tartışmalı olabilir.
Bi saniye — Bir de şu var. Eğer takımınız algoritmayı ezbere bilmiyorsa bakım maliyeti artabiliyor. Bu yüzden kurumsal projede genelde iyi yorum satırı isterim — hatta bazen mini diyagram bile koyarım. Aksi halde altı ay sonra kodu açan kişi yüzünde boş bir ifadeyle kalabiliyor. Bizzat yaşadım, o bakışı biliyorum.
Avantajlar ve Eksiler Bir Arada Düşünülmeli
Ne yalan söyleyeyim, En büyük avantaj tekrarlı karşılaştırmaları azaltması. Zaman karmaşıklığının O(N+M) seviyesinde kalması kağıt üstünde güzel görünür — ama pratikte bunun anlamı şu: büyük veride sürpriz azalır, tahmin edilebilirlik artar. Eksisi mi? Öğrenme eğrisi biraz dik, özellikle LPS ilk bakışta kafa karıştırabiliyor. Kaçınılmaz bu.
Pratik Kullanım İçin Küçük İpuçları
Eğer bunu kendi projenizde deneyecekseniz önce şunu sorun kendinize: problem gerçekten string araması mı? Bazen geliştiriciler regex ile çözülecek işi zorla algoritma dersine çeviriyor; bazen de tam tersi oluyor, performans gerektiren yerde düz yaklaşımı seçip CPU’yu gereksiz yoruyorlar. İki yönde de hata yapılıyor.
- LPS dizisini küçük örneklerle elle çıkarın;
- Aynı pattern üzerinde farklı text’lerle test edin;
- Elde ettiğiniz sonuçları naive search ile kıyaslayın;
- Büyük veri simülasyonu yapmadan karar vermeyin;
- Kodu genelde yorumlayın, özellikle `len` geçişlerini açıklayın;
Teknik boru hattında şöyle düşünün: pattern hazırlığı mutfağın önceden soğan doğraması gibi. İlk anda vakit gider, evet. Ama ana yemek piştiğinde işler hızlanır. Az önce hazırlığın bedeli var dedim ama şunu da ekleyeyim — doğru yerdeyse fazlasıyla geri döner. Yatırım mantığı işte.
Metni temizlemek veya ön işleme yapmak gerekebilir.
Bu detay çoğu demo yazıda atlanır.
Bence asıl hayal kırıklığı da burada başlıyor.
Sıkça Sorulan Sorular
KMP algoritması ne işe yarar?
KMP algoritması, büyük metinlerin içinde belirli bir deseni hızlı şekilde bulmak için kullanılır. Tekrar eden karşılaştırmaları azaltır ve bu yüzden özellikle uzun verilerde iyi çalışır. Hızlıdır ama öğrenmesi naif yönteme göre biraz daha zahmetlidir.
LPS dizisi neden gerekli?
LPS dizisi eşleşme bozulduğunda nereden devam edeceğinizi söyler. Böylece sıfırdan başlamak zorunda kalmazsınız. Aslında bütün numara burada yatıyor desem abartmış olmam.
KPM ile regex aynı şey mi?
Hayır,aynı şey değil. Regex çok daha esnekken KMP spesifik olarak sabit desen aramasına odaklanır. Performans ihtiyacı varsa ve desen netse KMP gayet iyi seçimdir.
Küçük projelerde KMP kullanmaya değer mi?
Bazen evet,bazen hayır: Eğer veri küçükse basit yöntem yeterlidir. Ama ileride ölçek büyüyecekse baştan sağlam temel atmak mantıklı olabilir.
Kaynaklar ve İleri Okuma
GeeksforGeeks — Knuth Morris Pratt Algorithm Explained
pCP-Algorithms — Prefix Function and String Matching
GitHub — String Searching Algorithms Collection
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



