2013-03-03 9 views
9

Şu anki durumum var: Büyük olasılıkla dizgiler (250.000'den fazla söyleyeyim) ortalama uzunluğu belki 30. Bunların içinde birçok arama yapmaktır. Bunlar çoğunlukla StartsWith ve İçerdekilerdir.whats en hızlı dize toplama yapısı/algoritması ile başlar ve/veya aramalar içerir

Koleksiyon çalışma zamanında statiktir. Bu, seçim koleksiyonunun ilk okuma ve doldurma işleminin sadece bir kez yapıldığı anlamına gelir. Bu nedenle, veri yapısını oluşturmanın performansı kesinlikle önemli değildir. Bellek de bir sorun değil: aynı zamanda gerekirse her biri için aynı veriyi içeren iki koleksiyona sahip olmamam gerektiği anlamına gelir (başlangıç ​​için bir tane diğeri için olan gibi). Sadece önemli olan, arama koşullarıyla eşleşen tüm öğeleri döndürmesi gereken aramaların performansıdır.

startswith için bir Trie veya Radix-ağacın üzerine geldi .. ama belki daha iyi seçimler vardır? İçin

I (alışkanlık veri bu miktarı ile çok hızlı olacak bir listedeki bir linq sorgusu çalıştıran yanında) henüz hiç iyi bir fikir var .. içeriyor.

Herkese şimdiden teşekkürler!

güncelleme: Önemli bir kısmını unuttular İçeren ile i koleksiyonunda kesin eşleşmeleri demek .. ama bir suffix tree sizi sağlayacak Bina verilen aranacak

+0

İçerir Aramanızın alt dizesi kelimelerle mi yoksa tek tek karakterlerle mi ilgileniyor? Bir indeks oluşturmanın bunun için anlamlı olup olmadığını merak ediyorum. –

+0

Karakterleri desteklemelidir. Performans nedenlerinden ötürü aramadan önce en az 3 veya daha fazla karakter vermeyi hayal edebiliyordum. (Sadece bazı karakterler girildikten sonra sadece bir karakter girildikten sonra bir metin kutusuna otomatik tamamlama gibi düşünebilirsiniz) – Mikk

+1

"Rabin Karp" için web'de arama yapın. Bu size bağlı birkaç arama algoritması olduğu için başlamanız gerekir ... http: //www.stoimen.com/blog/2012/04/02/bilgisayar-algoritmaları-rabin-karp-string-search/Ayrıca bir çiçek filtresi kullanma ve başlangıçta dizeleriniz ile önyükleme hakkında düşünün. – JimR

cevap

3

ihtiva koleksiyonundaki tüm dizeleri bulmak isterken O(1) içinde tüm dizelerinizde bir alt dizgi araması yapın. içimdeki bilgiçlik yardımcı ama n sizin alt dize eşleşmesi ve m alt dize boyutu sorgulanan olan dizeleri sayısıdır gerçekten O(n + m) var olduğuna dikkat olamaz.

Yani sormak bir sonek ağaç nedir? En basit uygulamasında, bir meraklı ekleme yöntemine sahip bir çentiktir: bir dizgenin eklenmesine ek olarak, bu dizgenin olası tüm soneklerini de trie'ye ekler. Bu veri yapısında, bir alt dizgi araması tüm olası soneklerin bir önek araması haline gelir. Ayrıca, önek aramalarını yapmak istediğinizden, eklenen her dizenin ve sorgu alt dizelerinin önüne özel bir karakter eklemek istersiniz. Özel karakter, bir sonek ve tam bir dize arasında ayrım yapmanıza izin verecektir. Bir sonek ağacının bu uygulama oldukça basit olsa da

, aynı zamanda (O(n^2) uzay ve zamanı inşa) çok verimsiz. Neyse ki, alanı ve zaman sınırlarını büyük ölçüde azaltabilen başka daha verimli uygulamalar var. Bunlardan biri olan Ukkonen'in algoritması, this SO answer'da çok iyi açıklanmış ve O(n)'a bağlı alanı getiriyor. Ayrıca, ek ağaçların eşdeğer ama daha etkili bir temsilidir suffix arrays içine bakmak isteyebilirsiniz.

Ben sadece bunları bilmiyorum (muhtemelen kullanım örneği için tatlı isabetli olurdu bunlardan biri) orada eki ağaçların çok çok daha fazla uygulama vardır bilirken. Bir uygulamaya geçmeden önce konuyla ilgili bazı araştırmalar yapmanızı tavsiye ederim.

+0

Eklenti ağacının verimsizliğinden yanılıyorsunuz. İyi bir uygulama O (n) veya O (n log n) zamanına ve O (n) boşluğuna dönüşebilir. http://en.wikipedia.org/wiki/Suffix_tree – nhahtdh

+0

Bu sesler şu ana kadar harika! özellikle sonek ve önekler arasında ayrım yapmak için özel char ile fikir! – Mikk

+0

Daha fazla okuyacağım ve bunu mutlaka deneyeceğim. Sonek dizileri hakkında bir dezavantaj olacak mı? Daha verimli olmaları durumunda muhtemelen onlara hemen odaklanacağım. – Mikk