SORU
6 Temmuz 2010, Salı


Hızlı dize arama algoritması nedir?

TAMAM, sorunu daha açık bir şekilde gereksinimleri/devlet gidiyorum salak gibi ses istemiyorum:

  • İğne (desen) ve Samanlık (arama, metin) hem de C-tarzı boş sonlandırılmış dizeler. Uzunluğun bilgi verilir; gerekirse, hesaplanmış olmalı.
  • Fonksiyon eğer eşleşme bulunursa ilk maçı, ya da NULL bir işaretçi döndürür.
  • Başarısızlık durumlarda izin verilmez. Bunun anlamı, herhangi bir algoritma ile sabit olmayan (ya da büyük sabit) depolama gereksinimleri var olan bir geri dönüş davası için ayırma hatası (ve performans geri dönüş bakım böylece katkı için en kötü durum performans).
  • Uygulama kodu olmadan algoritma (veya bağlamak için böyle iyi bir açıklama çok iyi olsa da C olmalı.

...yani ne kadar "hızlı":

  • *3 = * * * * * O(n) deterministik uzunluğu saman yığını. (Ama olabilir mümkün kullanın fikirleri algoritmaları olan normal O(nm) (örneğin rolling hash) eğer onlar birlikte daha sağlam bir algoritma ver deterministik O(n) sonuçlar).
  • Asla (kesinlikle; if (!needle[1]) birkaç saat vb. gerçekleştirir Tamam kötü saf kaba kuvvet algoritması daha, özellikle büyük olasılıkla en yaygın durumda olan çok kısa iğneler. (Ön koşulsuz ağır yükü büyük olasılıkla iğne pahasına patolojik iğneler için doğrusal katsayısı geliştirmek için çalışıyor gibi kötü.)
  • Keyfi bir iğne verildi ve Samanlık, benzer veya daha iyi performans (P daha uzun daha kötü hiçbir arama süresi) karşı başka bir yaygın olarak uygulanan bir algoritma.
  • Bu şartlar dışında, "en hızlı" açık uçlu. tanımı gidiyorum İyi bir cevap önerdiğin yaklaşım düşünün nedenini açıklamalı "hızlı".

Benim şu anki uygulamada yaklaşık  daha yavaş arasında 8 kat daha hızlı (giriş) bağlı olarak İki Şekilde abone olarak giriş bu uygulaması daha iyi çalışır.

Güncelleme: güncel optimum Benim algoritma aşağıdaki gibidir:

  • İğneler 1, strchr kullanmak için.
  • İçin iğne uzunluğu 2-4, kullanım makine kelimeler karşılaştırın 2-4 bayt anda şöyle: Ön iğne 16 - veya 32-bit tamsayı ile bitshifts ve döngü eski bayt/bayt cinsinden yeni gelen Samanlık her yineleme. Samanlık her bayt tam olarak bir kez okunur ve 0 (string sonu) ve bire karşı bir çek çeker 16 - veya 32-bit karşılaştırma.
  • Uzunluğu ^ iğneler için . 4, sadece pencerenin son byte uygulanan kötü vardiya tablosu (Boyer-Moore gibi) ile İki Yönlü bir algoritma kullanın. Önlemek için yük 1 KB başlatılıyor bir masa, bir net zararı pek çok orta boy iğne, duruyorum bir bit dizisi (32 bayt) işareti olan girişler kayması tablo başlatıldı. Geri Al bitler kendisi için tam iğne uzunlukta bir kaydırma mümkün asla iğne görünür olan değerler byte karşılık gelir.

Büyük soru aklımda kaldı

  • Bir şekilde kötü vardiya tablo daha iyi kullanmak için var mı? Boyer-Moore en iyi geriye doğru (sağdan sola) tarayarak onu kullanır ama İki Yönlü bir soldan sağa tarama gerektirir.
  • Genel durum için buldum sadece iki olası adaylar algoritmaları (yetersiz bellek veya kuadratik performans koşulları yok) Two-Way String Matching on Ordered Alphabets. Ama kolayca tespit edilebilir farklı algoritmalar optimal olacağı durumlar var mıdır? Kesinlikle boşluk algoritmaları O(m) m iğne uzunluğu (burada) birçok m<100 kadar kullanılabilir. Ayrıca kanıtlanabilir gerektirir sadece doğrusal zaman hangi kötü durum olan karesel eğer iğne için kolay bir test ise orada algoritmaları kullanmak mümkün olacaktır.

Bonus puan için:

  • İğne ve Samanlık iyi biçimlendirilmiş UTF-8, Her ikisi de kabul ederek performansını artırabilir mi? (Değişen bayt uzunlukta karakterler, iyi-oluşturulmuş-lik iğne ve Samanlık arasında bazı dize uyum gereksinimlerini etkiler ve eşleşmeyen bir kafa bayt karşılaşıldığında otomatik 2-4 byte vardiya sağlar. Ama bu kısıtlamaları satın çok bir şey ötesinde/sonek hesaplamaları, iyi soneki vardiya, vb maksimum yapın. zaten çeşitli algoritmalar ile verdin?)

Not:Peki pratikte nasıl gerçekleştirdiklerini algoritmaları en ama dışarıda değil, farkındayım. Burada insanlar algoritmalar beni referans veren/cevaplar yorum olarak tutmuyorum çok iyi bir referans: http://www-igm.univ-mlv.fr/~lecroq/string/index.html

CEVAP
6 Temmuz 2010, Salı


İğneler ve samanlıklarda büyük olasılıkla test bir kütüphane oluşturmak. Çeşitli arama algoritmaları, kaba kuvvet de dahil olmak üzere testler profili. En iyi veri ile gerçekleştiren bir seçim.

Boyer-Moore iyi soneki bir tablo ile kötü karakter tablosunu kullanır.

Boyer-Moore-Horspool kötü bir karakter tablosu kullanır.

Knuth-Morris-Pratt kısmi eşleşme tablosu kullanır.

Rabin-Karp çalışan sağlamalarının kullanır.

Onlar farklı bir dereceye kadar azaltılmış karşılaştırmalar için havai ticaret, gerçek dünya performansı hem de iğne ve Samanlık ortalama uzunlukları bağlıdır. Daha ilk yükü, daha uzun girişi ile. Çok kısa iğneler ile, kaba kuvvet kazansın.

Düzenleme:

Farklı bir algoritma baz çifti, İngilizce ifadeler, ya da tek bir kelime bulmak için en iyi olabilir. Eğer tüm girişler için en iyi algoritma olsaydı, kamuoyuna olurdu.

Aşağıdaki küçük tablo düşünün. Her soru işareti farklı en iyi arama algoritması olabilir.

                 short needle     long needle
short haystack         ?               ?
long haystack          ?               ?

Bu gerçekten bir grafik, her eksen üzerinde daha kısa ve daha fazla süreli girişler bir dizi olmalıdır. Eğer böyle bir grafik üzerinde her bir algoritma çizilen, her biri farklı bir imza olurdu. Bazı algoritmalar genler için arama gibi kullanır etkileyebilecek desen tekrarı bir sürü ile acı. Genel performansı etkileyen diğer bazı faktörler aynı model için birden fazla arama ve aynı zamanda farklı desenleri arıyor.

Eğer örnek bir ihtiyacım olursa, bir sitenin google veya wikipedia gibi kazımak, tüm sonuç sayfalarından html striptiz yapardım sanırım. Arama sitesi için bir kelime yazın sonra önerilen arama ifadeleri birini kullanın. Mümkünse birkaç farklı dil seçin. Web sayfalarını kullanarak, tüm metinleri orta, uzun metinleri almak için yeterli sayfaları birleştirme çok kısa olacaktır. Ayrıca kamu malı kitaplar, hukuki kayıtları ve diğer metin büyük organları bulabilirsiniz. Ya da sadece bir sözlükten kelime seçerek rastgele içerik üretmek. Ama profilleme noktası arıyor olacak içerik türüne karşı test, mümkünse gerçek dünya örnekleri kullanın.

Kısa ve uzun muğlak bıraktım. İğne için, altında 8 karakter, altında 64 karakter orta olduğunca kısa ve uzun olarak altında 1k düşünüyorum. Samanlık için 2^10, 2^20, ve uzun bir altında orta altında kısa 2^30 bir karakter olarak görüyorum.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Breno Rises

    Breno Rises

    7 Ocak 2014
  • Rachel Raum

    Rachel Raum

    10 EYLÜL 2007
  • RogerBuckChrist

    RogerBuckChr

    9 Temmuz 2011