Hızlı yazım denetleyicisi oluşturmak için verimli veri yapıları


41

Oldukça büyük bir sözlükle çalışması gereken bir yazım denetleyicisi yazmaya çalışıyorum. Hangi kelimelerin yanlış hecelenen kelimeye en yakın olduğunu belirlemek için Damerau-Levenshtein mesafesi kullanılarak kullanılmak üzere sözlük verilerimi endekslemek için etkili bir yol istiyorum .

Bana alan karmaşıklığı ile çalışma zamanı karmaşıklığı arasında en iyi uzlaşmayı sağlayacak bir veri yapısı arıyorum.

İnternette ne bulduğuma bağlı olarak, ne tür veri yapısını kullanacağımla ilgili birkaç ipucum var:

Trie

tray-500px

Bu benim ilk düşüncem ve uygulanması oldukça kolay görünüyor ve hızlı arama / yerleştirme sağlamalı. Damerau-Levenshtein kullanarak yaklaşık arama burada da uygulanması kolay olmalıdır. Ancak, alanların karmaşıklığı açısından çok verimli görünmüyor, çünkü büyük olasılıkla işaretçilerin depolandığı ek yüke sahipsiniz.

Patricia Trie

tray-500px

Bu, normal bir Trie'den daha az yer kaplıyor gibi görünüyor çünkü temel olarak işaretçileri saklama maliyetinden kaçınıyorsunuz, ancak sahip olduğum gibi çok büyük sözlükler söz konusu olduğunda veri parçalanması konusunda biraz endişeliyim.

Sonek Ağacı

soneki-500px

Bundan emin değilim, bazı insanlar metin madenciliğinde faydalı buluyor gibi görünüyor, ancak bir yazım denetleyicisi için performans açısından ne vereceğinden emin değilim.

Üçlü Arama Ağacı

tst

Bunlar oldukça hoş gözüküyor ve karmaşıklık açısından Patricia Tries'e yakın (daha iyi?) Olmalı, ancak Patricia Tries'den daha kötüsü olacaksa parçalanma konusunda emin değilim.

Burst Ağacı

patlamak

Bu biraz melez görünüyor ve Deneme ve benzerlerine göre ne gibi bir avantaj sağlayacağından emin değilim, ancak metin madenciliği için çok verimli olduğunu defalarca okudum.


Bu bağlamda hangi veri yapısının en iyi şekilde kullanılacağına ve onu diğerlerinden daha iyi yapan ne olduğuna dair geri bildirim almak istiyorum. Yazım denetleyicisine daha uygun bazı veri yapılarını özlüyorum, ben de çok ilgileniyorum.


Bir patricia trie, işaretçileri saklama maliyetini nasıl önler? Sadece bir en.wikipedia.org/wiki/Radix_tree mi? Eğer durum buysa, o zaman hala birçok işaretçi sakladığını düşünüyorum, ancak büyük ön tasarruflara sahip olacaksınız çünkü ortak önekler sadece bir kez saklanıyor
Joe

n

1
@ linker: Sözlüğünüz için tüm değişkenleri denediniz mi? Sabit bir kullanım durumu göz önüne alındığında, bu muhtemelen hangi veri yapısının ne kadar yer harcadığını bulmanın en hızlı yoludur.
Raphael

1
Sadece basit bir sözlük, sadece doğru yazılmış kelimelerin bilinen bir listesi.
Charles Menguy

Yanıtlar:


4

Aynı problemle karşılaştım ama farklı bir yaklaşım benimsedim. Benzer bir kelime için aynı veya yakın sayı verecek bir çeşit "karma" işlevi oluşturabilirsiniz.

Sorun şu ki, ekleme / çıkarma ile ilgili kelimeler için "iyi" bir sonuç verecek olan bu işlev, geçiş için "kötü" verecektir ve bunun tersi de geçerlidir. Örnek: Harfleri sayılarla eşleştirin, bitişik sayılarla aynı harften geçirin ve sadece her harften onları toplayın. Sonra her anahtar için kümeler içeren karma tablolar oluşturun ve sözcük kesişimini bulun.

Kelimelerin "boşluğuna" bakarsak bazı sonuçlar elde edilebilir. Harf değiştirme için X, ekleme / çıkarma için Y, geçiş için Z veya bunun gibi bir şey.

Ancak bu sadece soyut fikirler, onları uygulamak için yeterli zamanım yok.


Bu Soundex yaptığı iştir en.wikipedia.org/wiki/Soundex
rgrig

4

O(log(n))O

Dizeleri metrik ağaçta saklamayın. Sadece bir dizin saklayın ve dizeleri bir Patricia ağacında saklayın.

Hangi ağacı kullanman gerektiğinden emin değilim. Verilerinize ve gereksinimlerinize bağlı olacaktır (hızlı ekleme ihtiyacınız var mı?). Bir ağacın diğerlerinden daha verimli olduğunu tespit ederseniz sorunuzu güncelleyin.

Lucene gibi özel araçlara da bakabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.