En verimli şekilde merak 1.000 kelime sözlüğü dosyasında diyelim okuma ve daha sonra bir kaç paragraf olması demek başka belgeyi kontrol sağlayarak bir yazım denetleyicisi bir ikili arama ağacı yapmak.
Yazım denetleyicisi gibi bir ikili arama Ağacı Kullanımı
Bir üçlü ağaç tray daha verimli olacaktır
Bir otomatik yapmak gerekiyorsa yanı / önek arama önermek, ardından Patricia ağacı veya sayı tabanı ağaç bakarak değer.
Verdiğin örnek ile performans, tüm operasyon bunu göstermek ilk sonucu okumak için kullanıcı gereken süre yaklaşık% 1'ini alacak bir PC'de beri alakasız olması muhtemeldir Eğer tamamen aptal algoritma kullanmamak kaydıyla . Ama yine de sorun performansı bir mesele olduğunu yeterince büyük olduğunu varsayacağız.
Sözlük dosyası (çoğu gibi) ön ayrımı yapılır Eğer açıklamak gibi metin küçük göreceli sözlüğüne ise, o zaman ben şiddetle belki çiftleri kaldırarak, metin sıralamak için cazip olacağını ve daha sonra her iki listede yinelemenize yan -side her metin kelime yerine birleştirilmiş bir listesini çıkış sözlüğünde olup olmadığını rapor dışında, birleştirme tür ile aynı prosedürü kullanarak.
Bu tür M günlüğü M karşılaştırmaları hakkında işi yapar, artı yineleme için en N + M karşılaştırmalar, en (belki daha az, ancak karmaşıklığı daha az değil). Bu bir kerelik kullanım için en uygun karmaşıklığı oldukça yakın: sen hiç diskten tüm sözlüğü okuyamaz yollarını bulmalıyız N doğrusal vadede kurtulmak için. Onu özellikle kelimeler oldukça kısa olduğu göz önüne alındığında, dosyaya bsearch mümkün eminim, ama küçük N için bu yer hakkında arayan aslında seri verilere erişim daha hızlı olacak mı kimsenin tahmin.
Aşağıdaki özelliklere sahiptir:
- Sen bellekte sözlüğü, yalnızca metin tutmak gerekmez.
- Bununla birlikte, yalnızca sözlük dosyanın üzerine bir geçiş yapmak.
- Sen sözlüğe herhangi pahalı işlem yapmıyoruz.
Sözlük dosyası olarak ayrılmış önceden değilse Tabii o zaman bu işe yaramazsa ve o zaman ve içine işleme I / O maliyetini amorti edebilir sonraki imla çalışması için bellekte takılmak sözlüğü tutabilir eğer uzun vadede bir kazan olacak birkaç farklı metinler arasında bir ağaç.
Sözlük gerçekten büyük ise, o zaman dildeki çeşitli kelimelerin göreli frekanslarına göre ağırlıklandırılmış dengesiz ağacına önceden işlenmiş formu eşdeğer diskte saklayarak yarar olabilir. Sonra küçük metinler için daha az Ç (K), disk erişimini yapmak ve işletim belleğe yüklenerek rahatsız çoğu hiç, sadece dosya mmap ve bu konuda OS endişe izin üzerine olabilir. Büyük bir sözlüğe için, bütün kümeler "dimetil" ile başlayan kelimeleri içeren dokundu asla gerek yoktur.
Diğer bir faktör sözlük için bir yayvan bir ağaçtır. Eğer sık kullanılan değerler daha hızlı bulmak için yapmak için, içindeki şeyler aramak gibi bir yayvan ağaç kendini dengesizlikler. Çoğu metin defalarca kelime az sayıda kullanır, bu nedenle metin yükünü karşılayacak kadar uzunsa bu sonuçta kazanacak.
Yukarıdaki her iki dizeleri, bir tray normal ağaç yener Steven A Lowe noktaya tabidir. Yine de bir off-the-raf splay trie bulacaksınız olmadığını bilmiyorum.
Sadece belirli bir kelime senin sözlükte varsa (yani doğru yazıldığından olduğunu) görme çalışıyorsanız, o zaman bir ikili arama ağacı ne sonra konum olduğunu düşünmüyorum. ağacın her ardışık düğüm bir karakterdir ve son düğüme yolunu okuma sana o sözcüğün yazımını verir nerede bu bilgileri depolamak için daha iyi bir yolu bir ağaç tarzı olacaktır. Ayrıca kelime sonunu belirtmek için bir işaretçi ekleyin gerekiyordu.
Ör: araba, araba, kedi, fincan, kesme: En Sözlük bu kelimeler vardır ki
- C
- A
- R
- end
- T
- T
- end
- U
- P
- end
- T
- end
Bir kelime varsa denetleme tek tek her harfin bakarak meselesi olduğunu ve mevcut düğümün çocukları bulunmaktadır.
Check for "cat"
Does "C" exist at the root level? Yes, move to the next letter.
Does "A" exist underneath C? Yes, move on.
Does "T" exist underneath A? Yes, move on.
Is there a word ending after the T? Yes. Word exists.
Check for "cu"
Does "C" exist at the root level? Yes, move to the next letter.
Does "U" exist at the root level? Yes, move to the next letter.
Is there a word ending after the U? No. Word does not exist.
Saklamak nasıl bu bilgi size kalmış. Steven belirttiği gibi, bir Üçlü Arama Trie her bir düğüm 27 olası alt düğümleri olurdu: gitmek için yol olabilir.
Eğer bir ikili arama ağacı kullanılarak ölü-ayarlandı mı? Bir Bloom filtre belki de daha etkili bir veri yapısı olur.
Bu sana bir düz eski ikili ağaç (Kızıl-Siyah ağaçlar, AVL ağaçları, Radix ağaçlar, vs.) kullanmak zorunda olduğunu varsaymak gidiyorum bir ödev soru olduğunu görmek. Cevap o zaman kelime listeden oluşturdukça ağaç dengeli tutmaya çalışmaktır. Bir yaklaşım öncesinde bunu okuduktan listeyi rastgele etmektir, bu makul sonuçlar vermektedir. Eğer (ağaç kullandığı aynı karşılaştırmayı kullanarak) giriş dizisi sipariş Ama eğer o zaman yinelemeli hiçbir öğe kalmayıncaya kadar orta noktayı dönen girişi bölmek, daha iyi sonuçlar elde edebilirsiniz. Sonuç dengeli bir ağaçtır.
Ben C # bunu yapmanın üç farklı şekilde hamile:
private static IEnumerable<T> BinaryTreeOrder<T>(IList<T> range, int first, int last)
{
if (first > last)
{
yield break;
}
int mid = (first + last) / 2;
yield return range[mid];
foreach (var item in BinaryTreeOrder(range, first, mid - 1))
{
yield return item;
}
foreach (var item in BinaryTreeOrder(range, mid + 1, last))
{
yield return item;
}
}
private static void BinaryTreeOrder<T>(IList<T> range, int first, int last,
ref IList<T> outList)
{
if (first > last)
{
return;
}
int mid = (first + last) / 2;
outList.Add(range[mid]);
BinaryTreeOrder(range, first, mid - 1, ref outList);
BinaryTreeOrder(range, mid + 1, last, ref outList);
}
private static void BinaryTreeOrder<T>(IList<T> range, int first, int last,
ref BinaryTree<T> tree) where T : IComparable<T>
{
if (first > last)
{
return;
}
int mid = (first + last) / 2;
tree.Add(range[mid]);
BinaryTreeOrder(range, first, mid - 1, ref tree);
BinaryTreeOrder(range, mid + 1, last, ref tree);
}
Bu site java uygulaması vardır yardımcı olacaktır.
önerildiği gibi bir tray bir ikili ağacın daha verimli olacaktır, ancak bir hashmap kullanabilir ve her kelimeyi karma olabilir. Küçük bir sözlüğü (1000 kayıt) var. Belgenizi geçerken kelimeler HashMap ise, kontrol edin. Yerinde değilse, kelime yanlış varsayılır.
Bu yanlış yazılmış sözcüğe size mümkün düzeltme vermeyecektir. Sadece evet ya da hayır (doğru veya değil) söyler.
Yanlış kelimeler için yazım önerilerinde istiyorsanız o zaman, dosyada kelimesinden başlamak 1 düzenlemek mesafe uzaklıktadır tüm kelimeleri oluşturmak ve ilk kelimenin çocuklar gibi bunlar ekleyebilir. Böylece, bir grafiği inşa ediyoruz. doğruluk vs maksimum hız için derin 2 seviyeleri gidin. Eğer sözlükte bir kelime düğümü sağlıyorsa, olası öneri listesi ekleyebilirsiniz. Sonunda, olası önerilerin listesini döndürür.
Daha iyi yazım denetimi için, ayrıca fonetik eşleme eklemeyi deneyin.
deniz yuh -> yah bakın
(1 düzenlemek uzak şeritlerinin grafikler oluşturmak) Bu yöntem, "yavaş" dir. Ama iyi bir akademik alıştırma. Çalışma O (n ^ dallar) 'dir.
Birine bir bağlantı burada ilgi ise ben kendim oluşturdum (eğlence için): https://github.com/eamocanu/spellcheck.graph
Bazı örnek grafikleri: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos
Ayrıca grafikler üretir buna bir kullanıcı arayüzü bileşeni ilave edildi. Bu harici bir kütüphane.













