FEN BĠLĠMLERĠ ENSTĠTÜSÜ
DĠZGĠ EġLEME ALGORĠTMALARININ ĠNCELENMESĠ VE
YENĠ BĠR DĠZGĠ EġLEME ALGORĠTMASI
Abdul Kadir ERSĠN Yüksek Lisans Tezi
Bilgisayar Mühendisliği Anabilim Dalı DanıĢman: Yrd. Doç. Dr. Aydın CARUS
TRAKYA ÜNĠVERSĠTESĠ FEN BĠLĠMLERĠ ENSTĠTÜSÜ
DĠZGĠ EġLEME ALGORĠTMALARININ ĠNCELENMESĠ VE
YENĠ BĠR DĠZGĠ EġLEME ALGORĠTMASI
Abdul Kadir ERSĠN Yüksek Lisans Tezi
Bilgisayar Mühendisliği Anabilim Dalı
Bu tez 30/07/2008 tarihinde aşağıdaki juri tarafından kabul edilmiştir.
Yrd. Doç.Dr. Aydın CARUS Danışman
Yrd. Doç.Dr. Hilmi KUŞÇU Yrd. Doç.Dr. Altan MESUT
ÖZET
Yüksek Lisans Tezi, Dizgi Eşleme Algoritmalarının İncelenmesi ve Yeni Bir Dizgi Eşleme Algoritması, Fen Bilimleri Enstitüsü, Bilgisayar Mühendisliği Anabilim Dalı.
Bu tezde; günümüzde birçok alanda kullanılmakta olan dizgi eşleme algoritmaları incelenmiş, bu algoritmaların farklı alfabeler üzerindeki performansları belirlenerek, doğal dillerin yapısal farklılığının dizgi eşleme algoritmaları üzerindeki etkileri araştırılmıştır. Ayrıca alfabeyi oluşturan karakterleri gruplayarak bu grupların kullanım frekansına bağlı yeni ve hızlı bir dizgi eşleme algoritması sunulmuştur.
Dördüncü bölümde verilen deneme sonuçlarına göre, algoritmalar alfabeler üzerinden ele alındığında ortalamada DNA alfabesi üzerinde en etkin algoritma Shift Or, rakam alfabesi üzerinde Berry-Ravindran, doğal dil alfabesi üzerinde ise en etkili algoritma Tuned Boyer Moore algoritması olarak tespit edilmiştir. Ortalamada DNA alfabesinde en kötü performansı Reverse Factor, rakam ve doğal dil alfabesinde ise en kötü performansı Forward Dawg Matching algoritması sergilemiştir.
Araştırmada seçilen 8 farklı doğal dil için yapılan denemelerden elde edilen sonuçlara göre alfabe eleman sayısının algoritmaları etkilemesinin yanı sıra kullanılan doğal dillerin de algoritmaların performansını etkilediği belirlenmiştir.
Bu çalışmada sunulan, kullanılan alfabedeki karakterleri gruplayarak arama işlemi gerçekleştiren ve doğal diller üzerinde dizgi eşleme yapabilen yeni dizgi eşleme algoritması, doğal diller üzerinde en etkin performans gösteren diğer algoritmalardan daha etkin bir performans sergilemiştir.
Bu tez 2008 yılında yapılmıştır ve 128 sayfadan oluşmaktadır.
ANAHTAR KELİMELER: Dizgi Eşleme, Dizgi Eşleme Algoritmaları, Yaklaşık Dizgi Eşleme, Doğal Dil, Karakter Gruplama.
ABSTRACT
Graduate Thesis, Research into String Matching Algorithms and a New String Matching Algorithm, Graduate School of Natural and Applied Sciences, Department of Computer Engineering.
In this thesis; pattern matching algorithms are examined, their efficiencies over different alphabets are determined and the effects of structural differences of natural languages over pattern matching algorithms are researched. Besides, a fast pattern matching algorithm, which depends on group frequency of alphabet characters is presented.
According to the tests given in Section 4, the most efficient algorithms are; Shift Or for DNA alphabet, Berry-Ravindran for numeral alphabet and Tuned Boyer Moore for natural language alphabet. The worst algorithms are; Reverse Factor for DNA alphabet and Forward Dawg Matching for both numeral and natural language alphabets.
According to the test results of 8 different natural languages, it is identified that a pattern matching algorithm performance is affected not only with the total number of alphabet characters but also with structures of natural languages.
The new pattern matching algorithm that is presented in this thesis, which can make searching by grouping the alphabet characters and perform string matching on natural languages, had shown better performance on natural languages than other effective pattern matching algorithms.
This thesis was published in 2008 and consists of 128 pages.
KEYWORDS: String Matching, String Matching Algorithms, Approximate String Matching, Natural Language, Character Groupping.
TEġEKKÜR
Bu çalışmanın hazırlanmasında bana yol gösteren, her an ufkumu yeni bir bilgiyle açmaya çalışan, destek ve yardımlarını esirgemeyen değerli danışman hocam Yrd. Doç. Dr. Aydın CARUS’ a, çalışmalarımda ve tez yazımında bana yardımcı olan değerli hocam Yrd. Doç. Dr. Altan MESUT’ a, Yüksek Lisans eğitimi boyunca, gerek yayınlamış olduğum bildirilerimde gerek tezim için yapmış olduğum her türlü araştırmaların gerçekleştirilmesinde gerekli olan her türlü maddi ihtiyaçlarımın ve buna bağlı manevi ihtiyaçlarımın karşılanmasında büyük rol oynayan TÜBİTAK’a ve her an yanımda olan sevgili eşim ve aileme sonsuz teşekkürlerimi sunarım.
ĠÇĠNDEKĠLER
ÖZET... iii
ABSTRACT ... iv
TEġEKKÜR ... v
ĠÇĠNDEKĠLER ... vi
KISALTMALAR LĠSTESĠ ... viii
1. GĠRĠġ... 1
2. DĠZGĠ EġLEME ALGORĠTMALARI ... 4
2.1. Brute Force Algoritması... 5
2.2. Research with an Automaton Algoritması ... 6
2.3. Karp-Rabin Algoritması ... 8 2.4. Shift Or Algoritması ... 9 2.5. Morris-Pratt Algoritması ... 12 2.6. Knuth-Morris-Pratt Algoritması ... 14 2.7. Simon Algoritması ... 16 2.8. Colussi Algoritması ... 18 2.9. Galil-Giancarlo Algoritması ... 22 2.10. Apostolico-Crochemore Algoritması ... 24
2.11. Not So Naive Algoritması ... 27
2.12. Forward Dawg Matching Algoritması ... 28
2.13. Boyer-Moore Algoritması ... 30
2.14. Turbo-BM Algoritması ... 34
2.15. Apostolico-Giancarlo Algoritması ... 37
2.16. Reverse Colussi Algoritması ... 40
2.17. Horspool Algoritması ... 42
2.18. Quick Search Algoritması ... 43
2.19. Tuned Boyer-Moore Algoritması... 45
2.20. Zhu-Takaoka Algoritması... 46
2.21. Berry-Ravindran Algoritması ... 48
2.22. Smith Algoritması ... 49
2.23. Raita Algoritması ... 50
2.24. Reverse Factor Algoritması ... 52
2.25. Turbo Reverse Factor Algoritması ... 54
2.27. Galil-Seiferas Algoritması ... 59
2.28. Two Way Algoritması ... 62
2.29. String Matching On Ordered Alphabet Algoritması ... 65
2.30. Optimal Mismatch Algoritması ... 67
2.31. Maximal Shift Algoritması ... 69
2.32. Skip Search Algoritması ... 71
2.33. KMP Skip Search Algoritması... 72
2.34. Alpha Skip Search Algoritması ... 75
2.35. Diğer Algoritmalar ... 77
3. YAKLAġIK DĠZGĠ EġLEME. ... 80
3.1. Shift Or Algoritması ... 81
3.1.1. k uyuşmama sayısı ile dizgi eşleme... 82
3.1.2. k farklı sayısı ile dizgi eşleme ... 84
3.2. Wu-Manber Algoritması ... 87
4. DĠZGĠ EġLEME ALGORĠTMALARININ ALFABEYE BAĞLI ETKĠNLĠKLERĠNĠN ARAġTIRILMASI. ... 89
4.1. DNA Alfabesi Açısından Sonuçlar ... 90
4.2. Rakam Alfabesi Açısından Sonuçlar ... 92
4.3. Doğal Dil Alfabesi Açısından Sonuçlar ... 94
5. DĠZGĠ EġLEME ALGORĠTMALARININ DOĞAL DĠLLER ÜZERĠNDEKĠ DAVRANIġLARI. ... 97
6. KARAKTER GRUPLARININ FREKANSINI KULLANAN HIZLI YENĠ BĠR DĠZGĠ EġLEME ALGORĠTMASI (GF ALGORĠTMASI) ... 101
6.1. Grup Frekansı Algoritması ... 102
6.1.1. Ön işlem aşaması ... 102
6.1.2. Dizgi arama aşaması ... 104
6.2. Denemeler ve Sonuçlar ... 105
7. SONUÇLAR. ... 108
KAYNAKLAR ... 111
ÖZGEÇMĠġ ... 116
KISALTMALAR LĠSTESĠ
ASCII American Standard Code for Information Interchange BM Boyer-Moore
DAWG Directed Acyclic Word Graph DFA Deterministic Finite Automata DNA Deoxyribonucleic Acid
GB Gigabyte
GCC GNU C Compiler
GF Grup Frekansı Algoritması K-NN K-Nearest Neighbor
KB Kilobyte
KMP Knuth-Morris-Pratt
MAX Maksimum
MB Megabyte
MS Maximal Shift Algoritması
MIN Minimum
ODTÜ Orta Doğu Teknik Üniversitesi OM Optimal Mismatch Algoritması XML Extensible Markup Language
1. GĠRĠġ
Dizgi eşleme algoritmaları, metin işlemenin yaygın olarak kullanıldığı alanlarda çok önemli bir yere sahiptir. Dahası, sistem ve yazılım tasarımı gibi diğer bilgisayar bilimleri alanlarında kullanılan programlama yöntemlerinde sıkça kullanılmaktadırlar [Crochemore ve Rytter, 2002].
Verilerin metin dosyası şekli, bilgi alışverişinde büyük önem teşkil etmektedir. Özellikle çok büyük derlemlerin ve sözlüklerin kullanıldığı edebiyat ve dil bilimleri alanlarında bu durum daha önemli hale gelmektedir. Boyutları bu denli büyük dosyalar ile çalışıldığında bilgisayar kullanılması önemli performans artışı sağlamaktadır. Bu durum moleküler biyolojide de büyük önem teşkil etmektedir. Biyolojik moleküller deyince akla ilk aminoasitlerin ve nükleotidlerin dizilimi gelmektedir. Bu dizilimler bazen çok büyük boyutlara ulaşabilmektedir. İşte bu ve bunun gibi alanlarda istenen verilerin kolayca aranabilmesi problemi, dizgi eşleme algoritmalarına duyulan ihtiyacı ön plana çıkarmaktadır [Crochemore ve Lecroq, 1997]. Bilgisayar teknolojisi ne kadar gelişmiş olursa olsun, veri boyutu arttıkça etkili sonuçların alınabilmesi için daha hızlı ve kabul edilebilir bellek büyüklüklerinde çalışan algoritmalara ihtiyaç duyulmaktadır.
Dizgi eşlemede ∑ ile temsil edilen σ adet sonlu sayıda karakterden oluşan alfabe, hem x=x[0, 1, … , m-1] ile gösterilen uzunluğu m olan dizgi hem de uzunluğu n olan y=y[0, 1, ... , n-1] ile temsil edilen metnin oluşturulmasında kullanılır. Dizgi eşleme, metin içinde aranan dizginin en az bir ve genellikle tüm bulunduğu konumları bulmayı kapsamaktadır. Dizgi eşlemede, metnin hazırlanmasında kullanılan alfabe önem teşkil etmektedir. Dizgi eşleme algoritmalarının performansları kullanılan alfabeye göre farklılık gösterebilmektedir.
Aranılan dizginin sahip olmuş olduğu metin alanına “pencere” ismi verilmektedir ve bu pencere uzunluğu dizgi uzunluğu ile aynıdır ve m dir. Örneğin “kitap” dizgisinin penceresi “k” ve “p” karakterleri dahil olmak koşulu ile bu iki karakter arasındaki tüm alandır ve uzunluğu 5 tir. Dizginin, metin üzerinde eşlenme mantığı şu şekildedir:
Pencerenin en soldaki karakteri, yani ilk karakterden itibaren, üzerinde eşleme yapılacak olan metin ile hizalanır. Sonra karşılaştırma işlemi birbirleri ile hizalanan karakterler arasında gerçekleştirilir. Bu karşılaştırma işlemine “deneme” adı verilmektedir ve bütün bir uyuşma sonrası ya da uyuşmama sonrası pencere sağa doğru kaydırılır. Bu işlem metin sonuna kadar bu şekilde sürdürülür. Bu mekanizmaya “kayan
pencere mekanizması” adı verilmektedir [Charras ve Lecroq, 2004]. Dizgi eşleme
algoritmalarının tümü, eşleme yaparken bu mekanizma üzerinden çalışmaktadır.
Dizgi eşleme algoritmalarında, iki önemli kıstas, eşleme süresi ve karakter karşılaştırma sayısıdır [Carus vd., 2007]. Bu kıstaslar dizgi eşlemeyi gerçekleştiren algoritmanın performansını ortaya koymaktadır. Uygulamanın kullanılabilirliğine göre bu iki kıstas ayrı ayrı önem teşkil etmektedir. Fakat dizgi eşlemede performansın arttırılması yönündeki çalışmalar çoğunlukla eşleme süresi üzerinde gerçekleştirilmiştir. Eşleme süresi olarak bahsedilen kavram ise, aslında arama süresidir. Yani dizginin kayan pencere mekanizmasıyla eşleme yaparak, metinin sonuna kadar ulaşma süresidir. Karşılaştırma sayısı, algoritma üzerinde istisna bir mantığın çalışmaması koşuluyla, arama süresi ile doğru orantılıdır. Yani arama süresinin performansı çoğu zaman, karşılaştırma sayısının azlığı ya da çokluğu ile ilgilidir. Karşılaştırma sayısı ise, eşleme esnasındaki geri dönüşler ile birebir orantılıdır. Yani bir algoritma geri dönüşlere ne kadar az yer veriyorsa, karakter karşılaştırma sayısı da o kadar azdır ve buna bağlı olarak eşleme süresi de o kadar hızlıdır denebilir.
Buraya kadar bahsedilen dizgi eşleme, tam dizgi eşleme olarak da bilinmektedir. Bunun dışında, aranılan dizgiye yakın dizgiler bulmaya çalışan yaklaşık dizgi eşleme yöntemi de bulunmaktadır. Bu yöntem ise bir k yaklaşık değeri üzerinden gerçekleştirilmektedir. k yaklaşık değeri benzemenin, yani yaklaşıklılığın ne kadar olması gerektiğini belirleyen bir sayıdır. Günümüzde birçok arama motorunda yaklaşık dizgi eşleme kullanılmaktadır.
Bu çalışmada, tam dizgi eşleme üzerine geliştirilen algoritmalar ele alınarak, farklı alfabeler ve farklı dizgi uzunlukları üzerinde algoritmaların performanslarının araştırılması ve birbirleri ile kıyaslanmasının yanı sıra, yaklaşık dizgi eşleme konusuna
da değinilip, bu konuda geliştirilmiş algoritmalar da kapsanmaktadır. Ayrıca dizgi eşleme algoritmalarının farklı doğal diller üzerindeki davranışlarının da incelendiği bu çalışma, doğal dilin yapısal farklılıklarının, dizgi eşleme algoritmalarını etkilediğini ortaya koymaya çalışmaktadır [Ersin vd., 2007]. Çalışmada ayrıca metni oluşturan alfabedeki karakterleri frekansına göre gruplayarak arama yapan hızlı ve etkin yeni bir dizgi eşleme algoritması sunulmuş ve sunulan yeni algoritma, mevcut diğer algoritmalarla kıyaslanarak sunulan algoritmanın performansı belirlenmeye çalışılmıştır. Algoritmanın tüm dizgi uzunluklarında diğer tüm dizgi eşleme algoritmalarından daha hızlı olduğu saptanmıştır.
2. DĠZGĠ EġLEME ALGORĠTMALARI
Metin üzerinde eşleme yapmak amacıyla birçok algoritma geliştirilmiştir. Bu algoritmaların bir kısmı dizgiyi ön işlemeye yarayan ön işlem safhasını içerirken, bir kısmı ise bu safhayı içermemektedir. Ön işlem safhası aramayı daha etkin hale getirmek için dizgi üzerinde gerçekleştirilen işlemleri kapsamaktadır. Dizgi eşleme algoritmaları dizgi eşlerken dizgi üzerinde sağdan sola, soldan sağa, herhangi bir konumdan başlayarak ya da özel bir konumdan başlayarak karşılaştırma işlemini gerçekleştirmektedirler. Bütün bu konum tekniklerinin algoritmaya özgü etkinlikleri vardır.
Dizgi eşleme algoritmalarının performansı karmaşıklık olarak da bilinen Büyük
O (Big Oh) gösterimi ile ifade edilmektedir. Bu gösterim matematiksel bir gösterim
olup fonksiyonların davranışlarını tarif etmek için kullanılır. Bilgisayar biliminde ise algoritmaların bilgi işlemsel karmaşıklığının çözümlemesi için kullanılmaktadır [Krone ve Ogden, 2003].
Dizgi eşleme algoritmalarında Büyük O genellikle karakter, dizgi ve alfabe uzunluğu (m, n, σ) üzerinden ele alınmaktadır. Alfabe üzerinden ele alınmasının sebebi
ise, birçok algoritmada alfabe uzunluğunun algoritma performansı üzerindeki büyük etkisinden dolayıdır.
Dizgi eşlemede sabit alan ve doğrusallık diye bahsedilen terimler de mevcuttur. Sabit alandan aslında algoritmanın gerekli çalışma alanını tanımlamaktadır. Bu alan
O(1) olduğunda sabit alan sağlanmış demektir ve O(n) olduğunda algoritma doğrusal
zamanlıdır denmektedir. Bu özelliklere sahip bir algoritma etkindir denebilir. Sadece sabit alan ve doğrusallık üzerine yapılmış çalışmalar da mevcuttur [Rytter, 2002]. Çalışmamız sabit alanda çalışan algoritmaların yanında ekstra alana ihtiyaç duyan algoritmaları da kapsamaktadır.
Dizgi eşleme algoritmalarının performansı daha önce de belirtildiği üzere, arama süresi veya karşılaştırma sayısı ölçütleri üzerinden belirlenmektedir. Çoğu algoritmada
karşılaştırma sayısı ve arama süresi arasındaki bağıntı doğru orantılı olmaktadır. Fakat farklı bir teknik kullanan bazı algoritmalar bu orantıyı koruyamamaktadır. Bu sebepten dolayı her zaman için karşılaştırma sayısı arama süresi ile aynı oranda değişmektedir denemez.
Aşağıda ele alınmış olan dizgi eşleme algoritmaları tüm özellikleri ve çalışma prensipleriyle anlatılmaktadır. Buna ek olarak algoritmaların kaba koduna (Pseudo) da yer verilmiştir.
2.1. Brute Force Algoritması
2.1.1. Genel özellikleri
Önişlem safhası yok,
Ekstra sabit alan gereksinimi,
Her zaman kaydırma sağa doğru 1 birim, Herhangi bir düzende karşılaştırma,
Arama fazında zaman karmaşıklığı O(mn), 2n beklenen metin karakter karşılaştırması.
2.1.2. Tanımı
Brute Force algoritması metin içindeki 0 ve n-m arasındaki bütün pozisyonlarda, dizginin başlangıcından itibaren eşleşme olup olmadığını kontrol etmeye dayanmaktadır. Her deneme sonunda dizgi tam anlamıyla sağa doğru bir birim kaydırılır.
Brute Force algoritması hiçbir önişlem safhası gerektirmez, dizgi ve metine ek olarak ekstra sabit alana ihtiyacı vardır. Arama safhasında karşılaştırma işlemi herhangi bir düzende yapılabilir. Bu safhadaki zaman karmaşıklığı O(mn) (örneğin arama (an
üzerinde (am-1
b) dir). Beklenen metin karakter karşılaştırması 2n dir [Charras ve
Lecroq, 2004].
2.1.3. Kaba kodu
Arama Safhası
for j0 to metin_uzunluğu-dizgi_uzunluğu do
for i0 to dizgi_uzunluğu ve dizgi[i]=metin[i+j] do if i >= dizgi_uzunluğu then
Dizgi Bulundu
2.2. Research with an Automaton Algoritması
2.2.1 Genel özellikleri
∑ *
x (dizgiye ait karakterlerin oluşturduğu alfabe) dilinin tanımlanmasıyla en
düşük deterministik otomatı inşa eder,
Eğer otomat direk erişim tablosunda saklanıyorsa O(mσ) karmaşıklıkta ekstra alana ihtiyaç duyar,
Önişlem safhası O(mσ) zaman karmaşıklığına sahiptir,
Eğer otomat direk erişim tablosunda saklanıyorsa arama safhasında zaman karmaşıklığı O(n), diğer durumlarda ise O(nlog(σ)).
2.2.2. Tanımı
Bir x kelimesinin bir otomat üzerinden aranması işlemi, öncelikle ∑ *x dilinin
tanımlanmasıyla elde edilen en düşük deterministik sonlu durum otomatının (DFA) A(x) oluşturulmasına dayanmaktadır.
∑ *
x dilinin tanımlanmasıyla elde edilen DFA A(x)= (Q, q0, T, E) sırasıyla şu
şekilde tanımlanmaktadır:
Q , x e ait tüm öneklerin kümesi Q={ , x[0], x[0 .. 1], ... , x[0 .. m-2], x} q0= ; başlangıç durum
T={x}; aranılacak dizgi kümesi
q, Q için ( q, x in bir öneki) ve a, ∑ için, (q, a, qa) E ye ait, eğer sadece
qa x in öneki ise, diğer durumlarda ise (q, a, p) E ye ait, p, x in öneki
olan qa’ nın en uzun sonekidir.
DFA A(x) , O(m+σ) zamanda ve O(mσ) alanda düzenlenmektedir.
DFA A(x) nın ilk düzenlenme aşaması, y metninin içerisinde x kelimesi aranırken DFA A(x) y metinin üzerinde başlangıç konumunu hazırlar. Son durumun oluştuğu her durumda x in eşleşme durumu tutulur.
Eğer otomat direk erişim tablosunda saklanıyorsa arama safhasında zaman karmaşıklığı O(n), diğer durumlarda ise O(nlog(σ)) dir [Crochemore ve Hancart, 1997].
2.2.3. Kaba kodu
ÖniĢlem Safhası
for durum=başlanıca_hazırla (otomat) ve i0 to dizgi_uzunluğu do eski_hedefhedefi_al (otomat, durum, dizgi[i])
hedefyeni_zirve(otomat)
hedefi_ayarla (otomat, durum, dizgi[i], hedef) zirveyi_kopyala (otomat, hedef, eski_hedef) durumhedef
son_durumu_ayarla (otomat, durum)
Arama Safhası
otomatyeni_otomat(dizgi_uzunluğu+1, (dizgi_uzunluğu+1)*alfabe_uzunluğu) for durum=başlangıca_hazırla (otomat), j0 to metin_uzunluğu do
if (son_düğüm (otomat, durum)) then Dizgi Bulundu
2.3. Karp-Rabin Algoritması
2.3.1. Genel özellikleri
Bir hash(anahtar) fonksiyonu kullanır,
Önişlem safhası O(m) zaman karmaşıklığı ve sabit alan, Arama safhası O(mn) zaman karmaşıklığı,
O(m+n) beklenen çalışma zamanı.
2.3.2. Tanımı
Anahtarlama (hashing) çoğu pratik durumda kuadratik karakter karşılaştırmalarından sakınmak için kullanılan basit bir yöntemdir. Dizginin metin üzerindeki her pozisyonunun kontrolü yerine, eşleşen anahtar (hash) değer kümesinin karşılaştırılması, durumu daha etkili hale getirmektedir. Anahtar fonksiyonu benzer iki kelime arasında uygulanır. Dizgi eşleme algoritmalarında kullanılan anahtar fonksiyonundaki hash değeri aşağıdaki özelliklere sahip olmalıdır:
Etkili hesaplama,
Dizgiler için yüksek seçicilik,
hash(y[j+1..j+m]), hash(y[j..j+m-1]) ve y[j+m]: hash(y[j+1 .. j+m])=
rehash(y[j], y[j+m], hash(y[j .. j+m-1]) durumundan daha kolay
hesaplanabilir olması.
m uzunluktaki w kelimesi için hash (w) şu şekilde tanımlanır:
hash(w[0 .. m-1])=(w[0]*2m-1+ w[1]*2m-2+···+ w[m-1]*20) mod q, q çok büyük
sayı ve rehash(a,b,h)= ((h-a*2m-1
Karp-Rabin algoritmasının önişlem safhası hash (x) in hesabına dayanmaktadır. Bu işlem sabit alanda ve O(m) zamanda yapılmaktadır.
Arama safhası süresince hash (x) ve hash(y[j .. j+m-1]) değerlerini 0 j < n-m için karşılaştırmak yeterli olmaktadır. Eşitlik olması durumunda ise eşitlik x=y[j ..
j+m-1] üzerinden karakter karakter karşılaştırılması gerekmektedir.
Arama safhasındaki zaman karmaşıklığı O(mn), beklenen karakter karşılaştırması O(n+m) dir [Karp ve Rabin, 1987].
2.3.3. Kaba kodu Arama Safhası dizgiyi_belirli_bir_anahtarlama_fonksiyonuna_uyarla hxdizgiye_uyarlanan_anahtar_değeri dizgi_uzunluğu_kadar_metinin_ilk_parçasını_anahtarlama_fonksiyonuna_uyarla hymetin_parçasına_uyarlanan_anahtar_değeri while j <=metin_uzunluğu-dizgi_uzunluğu do if (hx=hy) then
karakterleri_karşılaştır, eşitlik sağlandığında, Dizgi_Bulundu
hy değerini sonraki metin parçası için yeniden düzenle j ++
2.4. Shift Or Algoritması
2.4.1. Genel özellikleri
Bitwise tekniğini kullanır,
Dizgi uzunluğunun makinenin kelime uzunluğundan kısa olduğu durumlarda etkilidir,
Önişlem safhasında O(m + σ) zaman ve alan karmaşıklığı,
Arama safhasında O(n) zaman karmaşıklığı (dizgi uzunluğu ve alfabe boyutuna bağlı),
Yaklaşık dizgi eşlemeye kolayca uyum sağlar.
2.4.2. Tanımı
Shift Or algoritması bitwise (bitler üzerinden mantıksal operatörlerle çalışma) tekniğini kullanır. Şekil 2.1’ de görüldüğü gibi R, m uzunluğundaki dizi parçası olmak üzere Rj vektörü y[j] metin karakterin işlenmesinden sonra ortaya çıkan R dizisinin değeridir. Bu değer metin içindeki y nin en son pozisyonunda bulunan xe ait uyuşan tüm öneklerin bilgisini içerir.
0 i m-1 için:
ġekil 2.1: Rj vektörünün ifadesi
Rj+1 vektörü Rj vektöründen sonra şu şekilde hesaplanır. Her Rj [i] =0 için:
Eğer Rj+1[m-1]=0 ise tüm eşleşme rapor edilebilir.
Rj den Rj+1 e geçiş şu şekilde daha hızlı hesaplanabilir. içindeki her c için Sc, m uzunluğundaki dizi parçası olsun. Bu durumda 0 i < m-1 için Sc[i]=0 iff x[i]=c olur.
Sc dizisi x dizgisi içerisindeki c karakterine ait pozisyonları ifade eder. Her Sc aramadan önce önişleme tabi tutulabilir. Ve Rj+1 in hesabı iki operasyona dönüşür, shift ve or : Rj+1=SHIFT(Rj) OR Sy[j+1].
Dizgi uzunluğunun makine kelime uzunluğundan uzun olmaması durumunda önişlem safhasındaki zaman ve alan karmaşıklığı O(m + σ) dir. Arama safhasında ise zaman karmaşıklığı dizgi uzunluğu ve alfabe boyutuna bağlı olarak O(n) olur [Baeza-Yates ve Gonnet, 1992].
2.4.3. Kaba kodu
ÖniĢlem Safhası
for i 0 to alfabe_uzunluğu do S[i] ~0
for limi0 to dizgi_uzunluğu j1, j<<=1 do S[dizgi[i]] &=~j
lim |=j lim=~(lim>>1) RETURN lim Arama Safhası
if dizgi_uzunluğu>bellek kelime uzunluğu then HATAYI_BİLDİR limÖnişlem_lim_değeri
for durum=~0 , j0 to metin_uzunluğu do durum (durum<<1) || S[metin[j]] if durum<limit değeri then
2.5. Morris-Pratt Algoritması
2.5.1. Genel özellikleri
Karşılaştırma işlemi soldan sağa doğru,
Önişlem safhasında alan ve zaman karmaşıklığı O(m),
Arama safhasında zaman karmaşıklığı O(m+n) (alfabe uzunluğuna bağlı),
Arama safhası esnasında en fazla 2n-1 metin karakter karşılaştırması, Gecikme m tarafından sınırlandırılmış.
2.5.2. Tanımı
Morris-Pratt algoritmasının tasarımı Brute Force algoritmasının iyi bir analizine dayanmaktadır ve özellikle bundan sonraki yöntem ise metin üzerindeki tarama esnasında biriktirilen bilginin tüketilmesine dayanır.
Brute Force algoritması daha yakından incelendiğinde, kaydırma uzunluğunu arttırmanın ve metin üzerindeki dizginin uyuşma sağladığı bazı parçaların eş zamanlı olarak hatırlamanın mümkün olduğu görülebilir. Bu durum, metin karakterleri ve dizgi karakterleri arasındaki karşılaştırma işlemini saklamakta ve bu durumun sonucunda arama hızını arttırmaktadır.
y üzerindeki bir sol j pozisyonda pencerede konumlanmış y[j..j+m-1] metin
elemanını baz alan denemeyi göz önünde bulunduralım. İlk uyuşmazlığın 0<i<m koşulunda x[i] ile y[i+j] arasında olduğunu farz edelim. Ve sonra x[0..i-1]=y[j..i+j-1]=u ve a=x[i] ≠y[i+j]=b.
Kaydırma sırasında dizgi üzerindeki v önekinin metin parçası üzerindeki u soneki ile uyuşmanın beklenmesi muhtemeldir. En uzun v soneki u nun sınırı olarak isimlendirilir. Bu durum şu sonucu ortaya koyar: 0 < i m için mpNext[i] , x[0...i-1] in en uzun sınır uzunluğu. Bir kaydırmadan sonra karşılaştırma metin üzerindeki dizginin
kayıpsız eşleşmesi ve metin üzerindeki geri dönüşlere yer vermeyerek şu şekilde devam eder: c=x[mpNext[i]] ve y[i+j]=b (Şekil 2.2). Sonra mpNext[0] =-1 yapılır.
ġekil 2.2: Morris-Pratt algoritmasında kaydırma işlemi (v u’nun sınırı)
mpNext tablosu önişlem safhasında O(m) zaman ve alan karmaşıklığında
hesaplanabilir. Arama safhası ise O(m+n) zaman karmaşıklığına sahiptir. Morris-Pratt algoritması arama safhası esnasında en fazla 2n-1 metin karakter karşılaştırması sağlamaktadır. Tek bir karakter için maksimum karşılaştırma sayısı (gecikme ) m ile sınırlıdır [Morris ve Pratt, 1970].
2.5.3. Kaba kodu
ÖniĢlem Safhası
i 0, jmpNext[0] -1 while i < dizgi_uzunluğu do
while j > -1 ve dizgi[i]≠ dizgi[j] do jmpNext[j]
mpNext[i++]++j Arama Safhası
ij0
while j<metin_uzunluğu do
while i>-1 ve dizgi[i]≠metin[j] do impNext[i]
i++, j++
if i >=dizgi_uzunluğu then Dizgi Bulundu i mpNext[i]
2.6. Knuth-Morris-Pratt Algoritması
2.6.1. Genel özellikleri
Karşılaştırma işlemi soldan sağa doğru,
Önişlem safhasında alan ve zaman karmaşıklığı O(m),
Arama safhasında zaman karmaşıklığı O(m+n) (alfabe uzunluğuna bağlı),
Gecikme log (m) tarafından sınırlandırılmış.
2.6.2. Tanımı
y üzerindeki bir sol j pozisyonda pencerede konumlanmış y[j..j+m-1] metin
elemanını baz alan denemeyi göz önünde bulunduralım. İlk uyuşmazlığın 0<i<m koşulunda x[i] ile y[i+j] arasında olduğunu farz edelim. Ve sonra x[0..i-1]=y[j..i+j-1]=u ve a=x[i] y[i+j]=b.
Kaydırma sırasında dizgi üzerindeki v önekinin metin parçası üzerindeki u soneki ile uyuşmanın beklenmesi muhtemeldir. Bundan başka, eğer başka bir uyuşamazlıktan sakınmak isteniyorsa, dizgideki v önekini takip eden karakterin a dan farklı olması gerekmektedir. En uzun v öneki u nun etiketlenmiş sınırı olarak isimlendirilir [Knuth vd., 1977].
Bu durum şu sonucu ortaya koyar: 0 < i m için kmpNext[i] , x[0...i-1] in en uzun sınır uzunluğu, c tarafından takip edilen ve x[i] ve -1 den faklı karakter. Bir kaydırmadan sonra karşılaştırma metin üzerindeki dizginin kayıpsız eşleşmesi ve metin üzerindeki geri dönüşlere yer vermeyerek şu şekilde devam eder: c=x[kmpNext[i]] ve
ġekil 2.3: Knuth-Morris-Pratt algoritmasında kaydırma işlemi (v u’nun sınırı ve c b) 2.6.3. Kaba kodu ÖniĢlem Safhası i 0, jkmpNext[0] -1 while i < dizgi_uzunluğu do while j > -1 ve dizgi[i]≠dizgi[j] do jkmpNext[j] i++, j++ if dizgi[i]=dizgi[j] then kmpNext[i]kmpNext[j] else kmpNext[i] j Arama Safhası ij0 while j< metin_uzunluğu do while i > -1 ve dizgi[i]≠metin[j] do ikmpNext[i] i++, j++ if i > dizgi_uzunluğu then Dizgi Bulundu ikmpNext[i]
2.7. Simon Algoritması
2.7.1. Genel özellikleri
∑*
x dilinin tanımlanmasıyla en düşük deterministik sonlu otomatın, A(x)
in ekonomik yorumlanması,
Önişlem safhasında O(m) zaman ve alan karmaşıklığı,
Arama safhasında O(m+n) zaman karmaşıklığı (alfabe uzunluğuna bağlı),
Arama safhasında en fazla 2n-1 karakter karşılaştırması, Gecikme min{1 + log2m, σ } ile sınırlandırılmış.
2.7.2. Tanımı
En küçük A(x) (DFA) ile arama işleminin temel sakıncası otomatın boyutudur:
O(m σ).
A(x) de kayda değer birkaç kenar değeri tespit edilmiştir. Bunlar;
İlerdeki kenarlar 0 k < m için x in k uzunluğundaki önekinden k+1 uzunluğuna gitmektedir. m kenarları.
Gerideki kenarlar x in k uzunluğundaki önekinden 0 (sıfır) olamayan uzunluktaki küçük öneke doğru gitmektedir. m ile sınırlanan kenarlar.
Diğer kenarlar ise başlangıç durumuna öncülük etmektedir ve daha sonra işlem görmektedirler. Bu kayda değer kenarlar ise 2m ile sınırlanmaktadır. Sonra otomatın her durumu için sadece önemli dış kenarlarının listeye kaydedilmesi gerekmektedir.
Her durum düzenli bir şekilde, -1 i m-1 için x[i] tarafından etiketlenen, her kenarın i durumuna öncülük ettiği, -1 öneki ile birleşen durumun uzunluğu ile temsil edilmektedir. Bu kenarların etiketlerinin saklanması gerekli değildir. İlerdeki kenarlar dizgi üzerinde kolayca anlaşılabilirler, bu nedenle saklanmazlar. Geriye sadece kayda değer geri kenarların saklanması kalır.
L tablosu m-2 uzunluğundaki bağlı liste olarak kullanılır. L[i] elementi i
başlangıç durumuna ait kenarların hedef listesini verir. Düzenli olarak m-1 durumuna ait listeyi saklamaktan sakınmak için, L tablosunun hesaplanması sırasında l değeri x in en uzun sınırı olan l+1 şeklinde hesaplanır.
Simon algoritmasının önişlem safhası L tablosunun ve l değerinin hesaplanmasını temel almaktadır. O(m) zaman ve alan karmaşıklığına sahiptir. Arama safhası bir otomat ile arama işlemi ile benzerdir. Dizgi üzerinde uyuşma bulunduğunda, geçerli durum l durumu ile güncellenir. Bu safha O(m+n) zaman karmaşıklığı ile sağlanır. Arama safhası boyunca en fazla 2n-1 karakter karşılaştırması yapılabilir. Gecikme (bir karakter için en fazla karşılaştırma sayısı) min{1+log2(m), σ} ile sınırlıdır [Simon, 1993].
2.7.3. Kaba kodu
ÖniĢlem Safhası
memset (L, NULL, (dizgi_uzunluğu-2)*(Listenin boyutu)) ell -1
for i1 to dizgi_uzunluğu do kell
cell (ell -1 ? NULL : L[k]) ell -1
if dizgi[i]=dizgi[k+1] then ellk+1
else
geçişi_ayarla (i-1, k+1, L)
while cell ≠NULL do k cell.element if dizgi[i]=dizgi[k] then ellk else geçişi_ayarla (i-1, k, L); cell cell.sonraki RETURN ell
Arama Safhası ell Önişlem_ell
for durum -1, j 0 to metin _uzunluğu do
durumgeçişi_al (dizgi, dizgi_uzunluğu, durum, L, metin[j]) if durum >= dizgi_uzunluğu-1 then
Dizgi Bulundu durum ell
2.8. Colussi Algoritması
2.8.1. Genel özellikleri
Knuth, Morris ve Pratt algoritmasının iyileştirilmiş halidir,
Dizgi iki ayrı kümeye ayrılır; birinci küme eşleşme olmadığı sürece soldan sağa doğru taranırken diğer küme sağdan sola doğru taranır,
Önişlem safhası O(m) zaman ve alan karmaşıklığına sahiptir, Arama safhası O(n) zaman karmaşıklığına sahiptir,
En kötü durumda n metin karşılaştırması yapar.
2.8.2. Tanımı
Colussi algoritmasının tasarımı Knuth, Morris ve Pratt algoritmasının sıkı bir analizine dayanmaktadır.
Dizgi konumu iki ayrı kümeye bölünür. Sonra her deneme iki safhayı içerir:
İlk safhada karşılaştırma kmpNext değerinin tam anlamıyla -1 den büyük olan değeri için dizgi pozisyonu ile hizalanmış metin karakterleri üzerinden soldan sağa doğru yapılır. Bu pozisyona
İkinci safha ise diğer kümenin sağdan sola doğru karşılaştırmasını içerir. Bu pozisyon ise delikli karĢılaĢtırma sıralaması olarak isimlendirilir.
Bu strateji iki avantajı ortaya çıkarmaktadır:
İlk safhada bir uyuşmazlık olduğunda, uygun kaydırmadan sonra bir önceki deneme süresince karşılaştırılmış olan hizalı deliksiz metin karakterleri ile karşılaştırmaya gerek yoktur.
İkinci safhada bir uyuşmazlık olduğunda, bu dizginin bir sonekinin metin faktörü üzerinde eşleştiği anlamına gelir, uygun kaydırmadan sonra dizginin öneki hala bir metin faktörüyle eşleşmektedir, sonra bu metin faktörünü tekrar karşılaştırmaya gerek yoktur.
0 i m-1: kmin[i]= d>0 için ancak ve ancak x[0 .. i-1-d]=x[d .. i-1] ve x[i-d] ≠ x[i], diğer durumlarda 0 (sıfır).
kmin ≠ 0 olduğunda bir frekans x içindeki i pozisyonu ile biter.
0 < i < m için eğer kmin[i-1] ≠ 0 ise i bir deliksiz, diğer durumda ise i bir
delikli.
nd+1, x içindeki deliksizlerin sayısı olsun.
h tablosu ilk nd+1 deliksizlerini artan sırada ve sonra m-nd-1 deliklilerini azalan
sırada içerir.
0 i nd için h[i] bir deliksiz ve 0 i<nd için h[i] < h[i+1]. nd < i < m için h[i] bir delikli ve nd < i < m-1 için h[i] > h[i+1].
Eğer i bir delikli ise rmin[i], i den büyük x in en küçük periyodudur.
x in y[j .. j+m-1] ile hizalandığını farz edelim. 0 k < r < nd için eğer x[h[k]]=y[j+h[k]] ve x[h[r]] ≠ y[j+h[r]] ise j’ = j+kmin[h[r]] olsun. y[j .. j’]
içerisindeki x in eşleşme durumu yoktur ve x, kmin[h[r]] konumu kadar sağa kaydırılabilir. (Şekil 2.4) Diğer taraftan 0 k < first[h[r]-kmin[h[r]]] için
x[h[k]]=y[j’+h[k]] durumu karşılaştırmanın x[h[first[h[r]-kmin[h[r]]]]] ve
y[j’+h[first[h[r]-kmin[h[r]]]]] şeklinde devam edebileceği anlamına gelmektedir.
ġekil 2.4: Bir deliksiz ile uyuşmama. Deliksizler siyah daireler ve soldan sağa doğru
karşılaştırılırlar.
Bu durumda, kaydırmadan sonra, ilk iki deliksizi karşılaştırmaya gerek yoktur.
0 k < r için eğer x[h[k]]=y[j+h[k]] ve nd r < m için x[h[r]] ≠ y[j+h[r]] ise y[j .. j’] içerisinde x in uyuşmama durumu söz konusudur ve x, kmin[h[r]] konumu
kadar sağa kaydırılır. Diğer taraftan x[0 .. m-1-rmin[h[r]]]=y[j’ .. j+m-1 ] durumu karşılaştırmanın x[h[first[m-1-rmin[h[r]]]]] ve y[j’+h[first[m-1-rmin[h[r]]]]] şeklinde devam edebileceği anlamına gelmektedir. (Şekil 2.5)
ġekil 2.5: Bir delikli ile uyuşmama.
Deliksizler siyah daireler ve soldan sağa doğru karşılaştırılırken, delikliler beyaz dairelerdir ve sağdan sola doğru karşılaştırılırlar. Bu durumda, kaydırmadan sonra, uyuşan dizgi önekinin tekrar karşılaştırılmasına gerek yoktur.
kmin değerini hesaplamak için hmax tablosu kullanılır ve şu şekilde tanımlanır: hmax[k] öyle ki x[k .. hmax[k]-1]=x[0.. hmax[k]-k-1] ve x[hmax[k]] ≠ x[hmax[k]-k].
nhd0[i] değeri i değerinden tam anlamıyla küçük deliksizlerin sayısıdır. shift ve next isimli iki fonksiyon şu şekilde tanımlanmaktadır:
i < nd için shift[i]=kmin[h[i]] ve next[i]=nhd0[h[i]-kmin[h[i]]]; nd i < m için shift[i]=rmin[h[i]] ve next[i]=nhd0[m-rmin[h[i]]] ; shift[m]=rmin[0] ve next[m]=nhd0[m-rmin[h[m-1]]].
Böylece, bir deneme esnasında pencerenin konumlanmış olduğu y[j .. j+m-1] metin faktörü üzerinde, x[h[r]] ve y[j+h[r]] arasında uyuşmama meydana geldiği zaman, pencere shift[r] kadar kaydırılır ve karşılaştırmalar h[next[r]] dizgi konumu boyunca devam edebilir. Algoritmanın önişlem safhası O(m) zaman ve alan karmaşıklığına sahiptir. Arama safhası O(n) zaman karmaşıklığına sahiptir. Ayrıca en kötü durumda n metin karşılaştırması yapar [Colussi, 1991].
2.8.3. Kaba kodu
ÖniĢlem Safhası
dizgi uzunluğundaki hmax, kmin, nhd0 ve rmin dizilerini düzenle; dizgi üzerinde delikli_deliksiz durumlarını sapta ve hmax dizisini oluştur; hmax değerine bağlı olarak kmin dizisini oluştur;
kmin ve hmax değerine bağlı olarak rmin dizisini oluştur; kmin değerine göre h dizisini oluştur;
bütün bu değerler bağlı olarak ve delikli_deliksiz tüm konumları shift adlı kaydırma değerinde topla; RETURN nd Arama Safhası ndÖnişlem_nd ij0, son -1 while j <= dizgi_uzunluğu-metin_uzunluğu do
while i< dizgi_uzunluğu ve son < j+h[i] ve dizgi[h[i]]=metin[j+h[i]] do
i++
if i>= dizgi_uzunluğu veya son >= j+h[i] then
Dizgi Bulundu
idizgi_uzunluğu if i> nd then
son j+dizgi_uzunluğu-1 jj+shift[i]
isonraki[i]
2.9. Galil-Giancarlo Algoritması
2.9.1. Genel özellikleri
Colussi algoritmasının iyileştirilmiş halidir,
Önişlem safhası O(m) zaman ve alan karmaşıklığı, Arama safhası O(n) zaman karmaşıklığı,
En kötü durumda n metin karakter karşılaştırması sağlar.
2.9.2. Tanımı
Galil-Giancarlo algoritması Colussi algoritmasının bir varyantıdır. Değişiklik arama safhasında meydana gelmektedir. Yöntem x in tek karakter üssü olmadığı zaman uygulanır (x≠cm, c elemanıdır ∑).
ℓ , 0 ≤ i≤ ℓ, x[0]=x[i] ve x[0] ≠ x[ℓ+1] için dizgi içindeki son indeks olsun. Bir önceki deneme süresince deliksizin eşleştiği ve dizgiye ait bir sonekin uyuştuğunu farz edersek bu, eş kaydırmadan sonra metin üzerindeki bir parçanın dizginin öneki ile uyuşacağı anlamına gelir. Böylece dizgi durumu y[j .. j+m-1] metin faktöründe konumlanır ve y[j .. son] parçası ile x[0 .. son-j] uyuşma gösterir. Sonra bir sonraki deneme süresince algoritma y[son+1] ile başlayarak metin sonuna ulaşana dek ya da
x[0] ≠ y[j+k] karakteri buluncaya kadar metini taramaya devam edecektir.
Bu durumdan sonra iki alt durum meydana gelmektedir:
x[ℓ+1] ≠ y[j+k] veya en azından x[0] bulunur (k ≤ ℓ) sonra dizgi konumu
algoritmasında olduğu gibi) ilk deliksiz ile ve dizginin hafızada tutulan öneki boş kelime olacak şekilde devam eder.
x[ℓ+1]=y[j+k] ve x[0] yeterli olarak bulunur (k > ℓ) sonra dizgi konumu y[k-
ℓ-1 .. k- ℓ+m-2] metin faktörü kadar kaydırılır, metin taraması (Colussi
algoritmasında olduğu gibi) ikinci deliksiz ile (x[ℓ+1] ilk deliksiz) ve dizginin hafızada tutulan x[0 .. ℓ+1] öneki olacak şekilde devam eder.
Önişlem safhası aynen Colussi algoritmasında olduğu gibi O(m) zaman ve alan karmaşıklığına sahiptir. Arama safhası O(n) zaman karmaşıklığına sahipken ayrıca en kötü durumda n metin karakter karşılaştırması sağlar [Galil ve Giancarlo, 1992].
2.9.3. Kaba kodu
for ell0 ve dizgi[ell]=dizgi[ell+1] do if ell=dizgi_uzunluğu-1
for jell0 to metin_uzunluğu do if dizgi[0]==metin[j] ell++ if ell>=dizgi_uzunluğu Dizgi Bulundu else ell0 else ÖniĢlem Safhası
nd=Önişlem_nd //Colussi Önişlem Aşaması Arama Safhası
ijağır_karakter0, son -1
while j<=metin_uzunluğu-dizgi_uzunluğu do if ağır_karater ve i=0 then
k son-j+1
while dizgi[0]=metin[j+k] do k++ if k<=ell veya dizgi[ell+1] ≠[j+k] then i0, jj+ (k+1), sonj-1;
else
i1, sonj+k, json-(ell+1)
ağır_karakter0
else
while i< dizgi_uzunluğu ve son<j+h[i] dizgi[ h[i]] =metin[j+h[i]] do
i++
if i>=dizgi_uzunluğu veya son>=j+h[i] then
Dizgi Bulundu
idizgi_uzunluğu;
if i>nd then sonj+dizgi_uzunluğu-1
jj+shift[i];
isonraki[i];
ağır_karakter(j< son ? 0:1)
2.10. Apostolico-Crochemore Algoritması
2.10.1. Genel özellikleri
Önişlem safhası O(m) zaman ve alan karmaşıklığı, Arama safhası O(n) zaman karmaşıklığı,
En kötü durumda n metin karakter karşılaştırması.
2.10.2. Tanımı
Apostolico-Crochemore algoritması kaydırma hesabı için Knuth-Morris-Pratt algoritmasındaki kmpNext kaydırma tablosunu kullanır.
x tek bir karakterin üssü (x=cm ve c , ∑ nin bir elemanı) olmak üzere ℓ=0 olsun ve ℓ, x[0] dan farklı olarak x in ilk karakter pozisyonuna eşit olsun (x=aℓ bu için a, b elemanıdır ∑, u elemanıdır ∑*
ve a ≠ b). Her deneme süresince karşılaştırma dizginin pozisyonları ile şu sırada gerçekleşmektedir: ℓ, ℓ+1, ... , m-2, m-1, 0, 1, ... , ℓ -1.
Şekil 2.6’da görüldüğü üzere arama safhası süresince ise i,j,k üçlüsüne dikkat çekilmektedir ki;
y[j .. j+m-1] metin faktörü zerinde konumlanmış; 0 k ℓ ve x[0 .. k-1]=y[j .. j+k-1];
l i < m ve x[ℓ .. i-1]=y[j+ l .. i+j-1].
Başlangıç üçlüsü (ℓ,0,0):
ġekil 2.6: Apostolico-Crochemore algoritmasında her denemedeki i,j,k
durumları
Şimdi i, j, k üçlüsü hesaplandıktan sonra sıradaki üçlünün nasıl hesaplandığını açıklayalım.
i değeri için 3 farklı durum ortaya çıkmaktadır:
i = l
Eğer x[i] = y[i+j] ise sıradaki üçlü (i+1, j, k).
Eğer x[i] ≠ y[i+j] ise sıradaki üçlü (ℓ, j+1, max{0, k-1}). ℓ < i < m
Eğer x[i] = y[i+j] ise sıradaki üçlü (i+1, j, k).
Eğer x[i] ≠ y[i+j] ise kmpNext[i] değeri için iki farklı durum ortaya çıkmaktadır:
kmpNext[i] ℓ: ise sonraki üçlü (ℓ, i+j-kmpNext[i], max{0,
kmpNext[i]})
i=m
Eğer k < ℓ ve x[k]=y[j+k] ise sonraki üçlü (i, j, k+1).
Diğer durumda k< ℓ ve x[k] ≠ y[j+k], veya k= ℓ, eğer k= ℓ olarak x üzerinde bir eşleşme olmuş ise. Her iki durumda da sıradaki üçlü ℓ
< i < m durumuna göre davranış gösterir.
Önişlem safhası kmpNext tablosunun ve ℓ sayı değerinin hesaplanmasını içermektedir. Bu safha O(m) zaman ve alanda yapılmaktadır. Arama safhası O(n) zaman karmaşıklığında yapılmakta ve en kötü durumda n metin karşılaştırması yapmaktadır [Apostolico ve Crochemore, 1991].
2.10.3. Kaba kodu
ÖniĢlem Safhası
Knuth_Morris_Pratt_Önişlem_Safhası for ell1 dizgi[ell-1]=dizgi[ell] do if ell=dizgi_uzunluğu then ell0 Arama Safhası
while j< metin_uzunluğu-dizgi_uzunluğu do
while i< dizgi_uzunluğu ve dizgi[i]=metin[i+j] do i++ if i >=dizgi_uzunluğu then
while k<ell ve dizgi[k]=metin[j+k] do k++ if k>=ell then
Dizgi Bulundu
jj+ (i- kmpNext[i]
if i=ell then kMAX(0,k-1) else
if kmpNext[i]<=ell then
kMAX(0, kmpNext[i]), iell
else
2.11. Not So Naive Algoritması
2.11.1. Genel özellikleri
Önişlem safhası sabit zaman ve alanda, Arama safhası O(nm) zaman karmaşıklığı, Ortalama durumda alt doğrusaldır.
2.11.2. Tanımı
Not So Naive algoritmasının arama safhası süresince karakter karşılaştırması dizgi konumunda şu sırada yapılır: 1, 2, ... , m-2, m-1, 0.
Her denemede pencere y[j .. j+m-1] metin faktöründe konumlanmakta: eğer
x[0]=x[1] ve x[1] ≠ y[j+1] ve eğer x[0] ≠ x[1] ve x[1]=y[j+1] ise dizgi 2 birim, diğer
durumlarda ise 1 birim kaydırılır. Böylece önişlem safhası sabit zaman ve alanda yapılmaktadır. Not So Naive algoritmasının arama safhası en kötü durumda kuadratik zaman karmaşıklığına sahip fakat ortalama durumda alt doğrusaldır [Hancart, 1992].
2.11.3. Kaba kodu ÖniĢlem Safhası if dizgi[0]=dizgi[1] then k2, ell1 else k1, ell2 Arama Safhası j0
while j<=metin_uzunluğu- dizgi_uzunluğu do if dizgi[1]≠metin[j+1] then jj+k
else
if eşleşme tam ve dizgi[0]=metin[j] then Dizgi Bulundu, jj+ell
2.12. Forward Dawg Matching Algoritması
2.12.1. Genel özellikleri
x in sonek otomatlarını kullanır,
En kötü durumda O(n) zaman karmaşıklığı,
Tam anlamıyla n metin karakter karşılaştırması sağlar.
2.12.2. Tanımı
Forward Dawg Matching algoritması metin içindeki sonlanan her pozisyon için en uzun dizgi elemanını hesaplar. Bu dizginin en küçük sonek otomatının kullanılmasını mümkün kılar. (DAWG olarak isimlendirilir. Directed Acyclic Word Graph-Çevrimsiz Kelime Grafiği). Bir kelimenin en küçük sonekli otomatı Deterministik Sonlu Otomattır
S(w) = (Q, q0, T, E).
L(S(w))={u , ∑* nın elemanı: w=vu öyle ki, v, ∑* nın elemanı }.
Forward Dawg Matching algoritmasının önişlem safhası x dizgisinin en küçük sonek otomatının hesaplanmasını içerir. Bu olay dizgi uzunluğu içerisinde, doğrusal zaman ve alanda yapılır.
Arama safhası süresince Forward Dawg Matching algoritması q0 başlangıç durumu ile S(x) otomatını kullanarak metin karakterlerinin soldan sağa doğru inceler.
S(x) içerisindeki her q durumu için q0 dan p ye en uzun yol length(q) olarak belirtilir. Bu yapı yaygın olarak sonek bağlantıları kavramını kullanır. Her p durumu için p nin sonek bağlantısı S[p] ile belirtilir. Bir p durumu için, Path(p)=(p0,p1, ... ,pℓ) p nin sonek yolu olsun, öyle ki p0=p, 1 i ℓ için, pi=S[pi-1] ve pℓ =q0. Her y[j] metin karakteri için ardıl olarak, p geçerli durum olsun, sonra Forward Dawg Matching algoritması
Path(p) nin ilk durumu için tanımlanmış bir geçiş olarak y[j] için tanımlanmış bir geçiş
alır. P geçerli durumu eğer bir Path(p) durumundan y[j] ile etiketlenmiş bir geçiş yok ise bu geçişin hedef durumu veya q0 başlangıç durumu ile güncellenir. length(p)=m olduğunda x e ait bir uyuşma bulunur.
Forward Dawg Matching algoritması tam anlamıyla n metin karakter karşılaştırması sağlar [Crochemore ve Ryteer, 1994].
2.12.3. Kaba kodu
ÖniĢlem Safhası
otomatyeniSonekOtomatı
(2*(dizgi_uzunluğu+2),2*(dizgi_uzunluğu+2)*Alfabe_Uzunluğu) SonekOtomatıİnşaEt (dizgi, dizgi_uzunluğu, otomat)
hazırlık_değişkenihazırlığı_al(otomat) Arama Safhası
ell0, durumhazırlık_değişkeni
for j0 to metin_uzunluğu do
if hedefi_al (otomat, durum, metin[j] tanımlanmamış değilse) then ++ell, durum hedefi_al (otomat, durum, metin[j])
else
while durum ≠ hazırlık_değişkeni ve hedefi_al ( otomat, durum, metin[j] tanımlanmamış) do durumSonekBağlantılarınıAl (otomat, durum)
if hedefi_al (otomat, durum, metin[j] tanımlanmamış değilse) then
elluzunluğu_al (otomat, durum) +1
durum hedefi_al(otomat, durum, metin[j])
else
ell0, durumhazırlık_değişkeni if ell= dizgi_uzunluğu then
2.13. Boyer-Moore Algoritması
2.13.1. Genel özellikleri
Karşılaştırma işlemi sağdan sola doğru sağlanır,
Önişlem safhası O(m+ σ) zaman ve alan karmaşıklığına sahiptir, Arama safhası O(mn) zaman karmaşıklığı,
Periyodik olmayan dizgilerin aramasında en kötü durumda 3n metin karakter karşılaştırması,
O(n / m) en iyi performans.
2.13.2. Tanımı
Boyer-Moore algoritması alışılmış uygulamalar için çok etkili bir algoritma olarak bilinmektedir. Algoritmanın basitleştirilmiş hali metin editörlerinde sıkça “ara ” ve “yerleştir” komutlarıyla yorumlanmaktadır.
Algoritma dizgi karakterlerinin en sağındaki karakterden başlayarak sağdan sola doğru arama işlemini gerçekleştirir. Uyuşmama durumunda (ya da tüm karakterlerin uyuşması durumunda) önceden hesaplanmış iki kaydırma fonksiyonu kullanmaktadır. Bunlar iyi-sonek (ya da uyuşma kaydırması) ve kötü-karakter (oluş kaydırması) olarak isimlendirilirler.
Bir denemede j pozisyonunda x[i]=a dizgi karakteri ve y[i+j]=b metin karakteri arasında bir uyuşmama meydana geldiğini farz edelim. Ve x[i+1 .. m-1]=y[i+j+1 ..
j+m-1]=u ve x[i] ≠ y[i+j] dir. İyi-sonek kaydırması x[i] den farklı bir karakterden önce
gelen x içerisindeki en sağdaki uyuşma ile y[i+j+1 .. j+m-1]=x[i+1 .. m-1] bölümünün hizalanması işlemlerini içerir. (Şekil 2.7)
ġekil 2.7: İyi-sonek kaydırması, a dan farklı bir c karakterinden önce gelen tekrar
uyuşan u.
Eğer böyle bir bölüm yok ise, kaydırma x in uyuşan öneki ile, y[i+j+1 .. j+m-1] nin en uzun v sonekinin hizalanmasını işlemini içerir. (Şekil 2.8)
ġekil 2.8: İyi-sonek kaydırması, x içerisinde tekrar eden sadece u soneki.
Kötü-karakter kaydırması, x[0 .. m-2] in en sağ uyuşan elemanı ile y[i+j] metin karakterinin hizalanmasını içerir. (Şekil 2.9)
ġekil 2.9: Kötü-karakter kaydırması, x içersindeki uyuşmayan a.
Eğer y[i+j], x dizgisi içerisinde yoksa y içerisindeki x in uyuşmayanını y[i+j] içerebilir, pencerenin en son sol karakteri y[i+j+1] ile hizalanır. (Şekil 2.10)
ġekil 2.10: Kötü-karakter kaydırması, x içersinde yer almayan b.
Kötü-karakter kaydırmasının negatif olabileceği göz önünde bulundurulmalıdır, bu yüzden kaydırma için, Boyer-Moore algoritması iyi-sonek ve kötü-karakter değerleri arasından maksimumu alır. Formül olarak bu iki fonksiyon şu şekilde tanımlanabilir:
İyi-sonek kaydırma fonksiyonu m+1 uzunluğundaki bmGs tablosunda saklanır. İki şart tanımlanması gerekirse:
Cs(i, s): her k için öyle ki i < k < m, s k veya x[k-s]=x[k] ve Co(i, s): eğer s <i ise x[i-s] ≠ x[i]
Sonra, 0 i < m için: bmGs[i+1]=min{s>0 : Cs(i, s) ve Co(i, s)} ve bmGs[0],
x in periyot uzunluğu olarak tanımlanır. bmGs hesabında suff tablosu kullanılır ki şu şekilde tanımlanır: 1 i < m için, suff[i]=max{k : x[i-k+1 .. i]=x[m-k .. m-1]}.
Kötü-karakter kaydırma fonksiyonu σ uzunluğundaki bmBc tablosunda saklanır. ∑ içindeki c için, bmBc[c] = min{i : 1 i <m-1 ve x[m-1-i]=c} eğer x in içinde c geçiyorsa, diğer durumlarda m.
bmBc ve bmGs tablolarının önişlem hesabı O(m+ σ) zaman ve alan
karmaşıklığına sahiptir. Arama safhasındaki zaman karmaşıklığı kuadratiktir fakat periyodik olmayan dizgide en fazla 3n metin karşılaştırması yapar. Geniş alfabelerde algoritma oldukça hızlıdır. En iyi performansta sadece O(n/ m) karşılaştırma yapar (bn
için am-1
b ) [Boyer ve Moore, 1977].
“Bu iki önişlem safhasından hangisinin algoritma hızına olan etkisi daha çoktur?” sorusu alt-dizgiler üzerinde ayrı bir çalışma konusu olarak ele alınmıştır. Bu
araştırmaya göre alt dizgileri (substring) kullanan ön işlem safhası yani iyi-sonek önişlem safhası çoğu zaman kötü karakter önişlem safhasına göre daha etkin bir kaydırma gerçekleştirmektedir [Stomp, 2003].
2.13.3. Kaba kodu
ÖniĢlem Safhası 1
for i0 to alfabe_uzunluğu do bmBc[i]dizgi_uzunluğu
for i0 to dizgi_uzunluğu-1 do bmBc[dizgi[i]]dizgi_uzunluğu-i-1
ÖniĢlem Safhası 2
sonekleri_tespit_et ( dizgi, dizgi_uzunluğu, sonek)
for i0 to dizgi_uzunluğu do bmGs[i]dizgi_uzunluğu, j0 for idizgi_uzunluğu-1 down to -1 do
if i=-1 veya sonek[i]=i+1 then
for to j dizgi_uzunluğu-1-i do if bmGs[j]=dizgi_uzunluğu then bmGs[j] dizgi_uzunluğu -1-i for i0 to dizgi_uzunluğu-2 do bmGs[dizgi_uzunluğu-1-sonek[i]] dizgi_uzunluğu-1-i Arama Safhası while j <=metin_uzunluğu-dizgi_uzunluğu do
for i (dizgi_uzunluğu -1) down to 0 ve dizgi[i]=metin[i+j] do if i <0 then Dizgi Bulundu jj+bmGs[0] else jj+MAX(bmGs[i], bmBc[metin[i+j]-dizgi_uzunluğu+1+i)
2.14. Turbo-BM Algoritması
2.14.1. Genel özellikleri
Boyer-Moore algoritmasının bir varyantıdır,
Boyer-Moore algoritmasına göre ekstra bir önişlem safhası gerektirmez, Boyer-Moore algoritmasına göre ekstra sabit alana ihtiyaç vardır,
Önişlem safhası O(m+ σ) zaman ve alan karmaşıklığı, Arama safhası O(n) zaman karmaşıklığı,
En kötü durumda 2n metin karakter karşılaştırması.
2.14.2. Tanımı
Turbo-BM algoritması Moore algoritmasının iyileştirilmiş halidir. Boyer-Moore algoritmasına göre ekstra sabit alan gerektirirken, ekstra bir önişlem safhasına ihtiyaç duymaz. Algoritma son deneme süresince dizginin soneki ile uyuşma gösteren metin faktörünü hatırlaması işlemine dayanmaktadır (ve eğer sadece iyi-sonek kaydırması sağlanmışsa).
Bu teknik iki avantaj sunmaktadır:
Bu faktörü atlamak mümkün olabilmektedir;
Bir turbo-kaydırma işleminin sağlanmasına yardımcı olabilmektedir.
Bir turbo-kaydırma, eğer geçerli deneme süresince dizgi soneki ile bununla uyuşan metin faktörü bir önceki denemeden hatırlanandan daha kısa olması durumunda gerçekleşmektedir. Bu durumda u hatırlanan faktör ve v geçerli deneme boyunca uyuşan soneki ve böylece uzv, x in bir soneki olsun. a ve b ise sırasıyla metin dizgi karakterleri üzerindeki uyuşmamaya sebep olan karakterler olsun. Sonra |v| < |u| olduğu sürece x in bir soneki olan av, u nun da soneki olur. a ve b karakterleri metin içinde p uzaklığında meydana gelir, |uzv| uzunluğundaki x in soneki, u, uzv nin bir sınırı olduğu sürece
farklı a ve b karakterlerinin ikilisinin uyuşmasını aşamaz. En küçük kaydırma |u|-|v| uzunluğundadır ve turbo-kaydırma olarak isimlendirilir. (Şekil 2.11)
ġekil 2.11: |v|<|u| durumunda meydana gelen bir turbo-kaydırma.
|v|<|u| durumunda eğer kötü-karakter kaydırmasının uzunluğu, iyi-sonek
kaydırması ve turbo kaydırma uzunluğundan daha uzun ise, güncel kaydırma |u|+1 ya eşit ya da büyük olmalıdır. Aslında bir önceki kaydırmanın iyi-sonek kaydırması olduğunu farz ettiğimiz sürece, bu durumda c ve d karakterleri birbirinden farklı iki karakterdir. (Şekil 2.12)
ġekil 2.12: c ≠ d, böylece v içerisindeki aynı karakterle hizalanamaz.
|u|+1 den küçük ve turbo-kaydırmadan büyük bir kaydırma, c ve d karakterleri v
içerisindeki benzer karakter ile hizalanabilir. Böyle bir durum olduğunda ise güncel kaydırmanın uzunluğu en az |u|+1 olmalıdır.
Önişlem safhası O(m+ σ) zaman ve alan karmaşıklığına sahiptir. Arama safhası
O(n) zaman karmaşıklığına sahiptir. Metin karakter karşılaştırma sayısı 2n ile sınırlıdır
2.14.3. Kaba kodu ÖniĢlem Safhası Boyer_Moore_Önişlem_Safhası_1 Boyer_Moore_Önişlem_Safhası_2 Arama Safhası ju0, shiftdizgi_uzunluğu
while j<= metin_uzunluğu - dizgi_uzunluğu do i dizgi_uzunluğu-1;
while i>=0 ve dizgi[i]= metin[i+j] do i--
if u ≠0 (sıfır) ve i= dizgi_uzunluğu-1-shift then ii-u
if i< 0 then
Dizgi Bulundu shiftbmGs[0]
udizgi_uzunluğu-shift
else
vdizgi_uzunluğu-1-i, turboshiftu-v
bcShiftbmBc[metin[i+j]]-dizgi_uzunluğu+1+i shiftMAX(turboShift, bcShift)
shiftMAX(shift, bmGs[i])
if shift=bmGs[i] then uMIN(dizgi_uzunluğu-shift, v) else
if turboShift< bcShift then shiftMAX(shift,u+1) u0
2.15. Apostolico-Giancarlo Algoritması
2.15.1. Genel özellikleri
Boyer-Moore algoritmasının varyantıdır,
Önişlem safhası O(m+ σ) zaman ve alan karmaşıklığı, Arama safhası O(n) zaman karmaşıklığı,
En kötü durumda n metin karakter karşılaştırması.
2.15.2. Tanımı
Boyer-Moore algoritmasının analizi zordur çünkü her denemeden sonra uyuşma gösteren karakterler unutulmaktadır. Bu algoritma her deneme sonunda pencerenin en sağ sonundaki dizginin en uzun sonekini hatırlayabilen bir algoritmadır. Bu bilgi ise
skip isimli bir tabloda tutulmaktadır. Bir deneme esnasında j den küçük bir konumda,
algoritmanın 0 < i < m için i+j konumunda k uzunluğundaki x in soneki ile uyuşma gösterdiğini farz edersek, skip[i+j] tablo değeri k ya eşit olur. suff[i], 0 i < m için, x içerisindeki i konumu sonunda bulunan x in en uzun sonek uzunluğuna eşit olsun.
Deneme esnasında j konumunda, eğer algoritma y[i+j+1 .. j+m-1] metin faktörünü başarılı bir şekilde karşılaştırmışsa dört farklı durum ortaya çıkmaktadır:
Durum1: k > suff[i] ve suff[i]=i+1. Bu, j konumunda x uyuşması bulunduğu
anlamına gelmektedir ve skip[j+m-1] değeri m ye eşitlenir. Bir per(x) uzunluğundaki kaydırma sağlanmıştır.(Şekil 2.13)
Durum 2: k > suff[i] ve suff[i] i. Bu, x[i-suff[i]] ve y[i+j-suff[i]] karakterleri
arasında bir uyuşmama meydana geldiği anlamına gelmektedir ve skip[j+m-1] değeri
m-1-i+suff[i] ye eşitlenir. bmBc[y[i+j-suff[i]]] ve bmGs[i-suff[i]+1] kullanılarak bir
kaydırma sağlanmıştır. (Şekil 2.14)
ġekil 2.14: y[i+j-suff[i]] ve x[i-suff[i]] arasında bir uyuşmama meydana geldi.
Durum 3: k < suff[i]. Bu, x[i-k] ve y[i+j-k] karakterleri arasında bir uyuşmama meydana geldiği anlamına gelmektedir ve skip[j+m-1] değeri m-1-i+k ye eşitlenir.
bmBc[y[i+j-k]] ve bmGs[i-k+1] kullanılarak kaydırma sağlanmıştır. (Şekil 2.15)
ġekil 2.15: y[i+j-k] ve x[i-k] arasında bir uyuşmama meydana geldi.
Durum 4: k=suff[i]. Bu durum sadece y[i+j-k+1 .. i+j] metin faktörü üzerinden
bir "jump" ile gerçekleştirildiğinde y[i+j-k] ve x[i-k] karakterleri arasında düzenli olarak karşılaştırmaya devam edildiğinde gerçekleşir. (Şekil 2.16)