Karma Tablo ile Üçgen (Ön Ek Ağacı) Arasında Nasıl Seçim Yaparım?


134

Bir karma tablo veya bir önek ağacı arasında seçim yapmak zorunda kalırsam, diğerini seçmeme neden olacak ayırt edici faktörler nelerdir. Kendi saf bakış açımdan, bir dizi olarak saklanmadığı için bir trie kullanmanın ekstra bir yükü varmış gibi görünüyor, ancak çalışma süresi açısından (en uzun anahtarın en uzun İngilizce kelime olduğu varsayılarak) aslında O olabilir (1) (üst sınırla ilişkili olarak). Belki de en uzun ingilizce kelime 50 karakterdir?

Hash tabloları indeksi aldıktan sonra anında arama yapar . Ancak endeksi almak için anahtar karma kolayca kolayca 50 adım alabilir gibi görünüyor.

Birisi bana bu konuda daha deneyimli bir bakış açısı sağlayabilir mi? Teşekkürler!


1
Bir redix ağacının düz bir üçlüden daha verimli olduğunu belirtmek gerekir, çünkü her dize baytı için yeni bir şubeye ihtiyacınız yoktur. Ayrıca, redix ağaçları, karma tablolardan daha iyi "bulanık" aramalar için destek sağlar, çünkü yolda çalışırken tek tek bitlere bakıyorsunuzdur. Örneğin 00110010, girdi baytı olabilir, ancak 00111010yalnızca bir bit kaldırılan eşleşmeyi dahil etmek istersiniz .
Xeoncross

Yanıtlar:


116

Denemenin avantajları:

Temeller:

  • K'nin anahtarın boyutu olduğu tahmin edilebilir O (k) arama süresi
  • Arama, orada yoksa k'dan daha az zaman alabilir
  • Sıralı geçişi destekler
  • Karma fonksiyona gerek yok
  • Silme basittir

Yeni operasyonlar:

  • Anahtarların öneklerini hızlı bir şekilde arayabilir, belirli bir önekle tüm girişleri numaralandırabilirsiniz.

Bağlantılı yapının avantajları:

  • Çok sayıda yaygın önek varsa, ihtiyaç duydukları alan paylaşılır.
  • Değişmez denemeler yapıyı paylaşabilir. Bir trie'yi yerinde güncellemek yerine, sadece bir dal boyunca, başka bir yerde eski trie'ye işaret eden yeni bir tane oluşturabilirsiniz. Bu, eşzamanlılık, bir tablonun aynı anda birden çok sürümü vb. İçin yararlı olabilir.
  • Değişmez bir üçlü sıkıştırılabilir. Yani, hash-consing ile soneklerin yapısını da paylaşabilir .

Hashtables avantajları:

  • Herkes hashtabloları biliyor, değil mi? Sisteminizde zaten pek çok amaç için denenden daha hızlı, iyi optimize edilmiş güzel bir uygulama olacak.
  • Anahtarlarınızın özel bir yapısı olması gerekmez.
  • Bağlantılı trie yapısından daha fazla yer tasarrufu sağlar ( aşağıdaki yorumlara bakın )

27
"bariz bağlantılı trie yapısından daha fazla yer tasarrufu sağlayan" ile oldukça aynı fikirde değil - genel bir karma tablo uygulamasında, anahtarları içermek için çok daha fazla yer kaplarken, denemelerde her düğüm bir kelimeyi temsil eder. Bu anlamda, denemeler daha fazla yer tasarrufu sağlar.
galactica

1
bir yapıdan diğerine veri aktarmaya ne dersiniz? Önbellek ve konum düşünüyorum
Horia Toma

8
@galactica, deneyimlerimle çelişiyor: örneğin, uzay için ölçtüğüm tüm yapıların bu cevabında , bir trie en kötüsü oldu. İşaretçi bayttan çok daha büyük olduğu için bu mantıklıdır. Evet, öneklerin paylaşımı yardımcı olur, ancak pariteye ulaşmak için çok fazla ek yükün üstesinden gelmek zorundadır. Daha fazla yer tasarrufu sağlayan bir temsil çok yardımcı olabilir, ancak o zaman artık belirgin bağlantılı yapıdan bahsetmiyoruz.
Darius Bacon

1
@DariusBacon telefon numaralandırma planlarını ele almak denemeler için makul bir senaryo gibi görünüyor. Örnek senaryo: operatöre uygun telefon numarası. bir taşıyıcıdan diğerine taşınan numaralar. Her zamanki sözlükler için dile (Mandarin - İngilizce) bağlı olabilir, n-gram ve / veya diğer istatistiksel verilere ihtiyacınız olacaktır. Bir kafiye kitabı için bir ek ağacı da iyi bir seçenek gibi görünüyor.
mbx

Arama için verilerin çeşitliliği çok önemlidir. Veri değerlerinizin büyük bir kısmı benzersizse, ek boş işaretçiler kullanması nedeniyle alan karmaşıklığınız karma değerinde artacaktır.
Örnek

45

Her şey hangi sorunu çözmeye çalıştığınıza bağlıdır. Yapmanız gereken tek şey eklemeler ve aramalarsa, bir karma tablo ile gidin. Önek ile ilgili sorgular gibi daha karmaşık sorunları çözmeniz gerekiyorsa, bir üçlü daha iyi bir çözüm olabilir.


8
karma tablo ve trie sorguda aynı karmaşıklığa sahipse, k uzunluk dizesi için O (k) neden karma için gitmeliyiz? lütfen açıklar mısın?
Sazzad Hissain Khan

29

Herkes hash tablosunu ve kullanımlarını bilir, ancak tam olarak sürekli arama süresi değildir, hash tablosunun ne kadar büyük olduğuna, hash fonksiyonunun hesaplama karmaşıklığına bağlıdır.

Verimli arama için büyük karma tablolar oluşturmak, küçük gecikme / ölçeklenebilirliğin bile önemli olduğu endüstriyel senaryoların çoğunda zarif bir çözüm değildir (örn: yüksek frekans ticareti). Önbellek kaybını azaltmak için bellekte kapladığı alan için de optimize edilecek veri yapılarına dikkat etmelisiniz.

Trie'nin gereksinimlere daha uygun olduğu çok iyi bir örnek mesajlaşma ara yazılımıdır. Çeşitli kategorilere (JMS terimleri - Konular veya borsalarda) bir milyon aboneniz ve yayıncınız var, bu gibi durumlarda konulara (aslında dizeler olan) iletileri filtrelemek istiyorsanız, kesinlikle karma tablo oluşturmak istemezsiniz. milyon konu ile milyon abonelik için. Daha iyi bir yaklaşım, konuları üçlü olarak depolamaktır, bu nedenle filtreleme konu eşleşmesine göre yapıldığında karmaşıklığı konu / abonelik / yayıncı sayısından bağımsızdır (yalnızca dizenin uzunluğuna bağlıdır). Alan gereksinimlerini optimize etmek ve bu nedenle önbellek kaybının daha düşük olması için bu veri yapısıyla yaratıcı olabilirsiniz.


11

Bir ağaç kullanın:

  1. Otomatik tamamlama özelliğine ihtiyacınız varsa
  2. 'A' veya 'axe' ile başlayan tüm kelimeleri bul.
  3. Son ek ağacı özel bir ağaç şeklidir. Sonek ağaçlarının, hashın karşılayamayacağı avantajların bir listesi vardır.

4

Aklımızda tutmanın önemli olduğunu düşündüğüm kimsenin açıkça bahsetmediğini gördüğüm bir şey var. Hem hash tabloları hem de çeşitli tür denemeleri, genellikle dizenin bit cinsinden (veya karakter cinsinden eşdeğer olarak) uzunluğu olan O(k)işlemlere sahip olacaktır k.

Bu iyi bir hash fonksiyonuna sahip olduğunuzu varsayar. "Çiftlik" ve "çiftlik hayvanları" nın aynı değere hash olmasını istemiyorsanız, karma işlevinin anahtarın tüm bitlerini kullanması gerekir ve bu nedenle karma "çiftlik hayvanları" yaklaşık iki kat daha uzun sürmelidir "farm" (bir tür haddeleme karma senaryosunda değilseniz, ancak denemelerde de benzer şekilde çalışma tasarrufu sağlayan senaryolar vardır). Ve bir vanilya trie ile, "çiftlik hayvanları" eklemenin neden "çiftlik" ten iki kat daha uzun süreceği açıktır. Uzun vadede sıkıştırılmış denemelerle de doğrudur.


3

Bir trie üzerine ekleme ve arama, O (s) giriş dizgisinin uzunluğu ile doğrusaldır.

Bir karma size arama ve ekleme için bir O (1) verecektir, ancak önce karma değerini yine O (s) olan giriş dizesine göre hesaplamanız gerekir.

Sonuç olarak, asimtotik zaman karmaşıklığı her iki durumda da doğrusaldır.

Üçgen, veri perspektifinden biraz daha fazla ek yüke sahiptir, ancak sizi karma tabloyla bir kravat üzerine daha fazla veya daha az tekrar koyacak sıkıştırılmış bir üçlü seçebilirsiniz.

Beraberliği kırmak için kendinize şu soruyu sorun: Sadece tam kelimeleri aramam gerekiyor mu? Yoksa bir önekle eşleşen tüm kelimeleri döndürmem gerekiyor mu? (Akıllı metin giriş sisteminde olduğu gibi). İlk durumda, bir karma için gidin. Daha basit ve daha temiz bir koddur. Test edilmesi ve bakımı daha kolaydır. Ön eklerin veya sufix'lerin önemli olduğu daha ayrıntılı bir kullanım durumu için bir üçe gidin.

Ve sadece eğlenmek için yaparsanız, bir üçlü takmak bir Pazar öğleden sonra iyi bir kullanım sağlar.


Msgstr "Bir karma size arama ve ekleme için bir O (1) verecektir, ancak önce karma değerini yine O (s) olan giriş dizesine göre hesaplamanız gerekir." Bunu açıkladığınız için teşekkürler!
abadawi

Karma işlevinin hesaplanması O (s) değildir. Aslında O (1). Hesaplamak için dizenin tüm bitlerine ihtiyacınız yoktur, bazıları (sabit sayıda) yeterlidir.
Nicola Amadio

2

HashTable uygulaması temel ile karşılaştırıldığında yerden tasarruf sağlar Trie ile uygulamasına . Ancak dizelerle, pratik uygulamaların çoğunda sıralama gereklidir. Ancak HashTable sözlükbilimsel düzeni tamamen bozar. Şimdi, uygulamanız sözlük sırasına (kısmi arama, önek verilen tüm dizeler, sıralı düzendeki tüm kelimeler) dayalı işlemler yapıyorsa, Denemeleri kullanmalısınız. Yalnızca arama için HashTable kullanılmalıdır (tartışmalı olarak minimum arama süresi verir).

Not: Bunların dışında Üçlü Arama Ağaçları (TST'ler) mükemmel bir seçim olacaktır. Arama süresi HashTable'dan daha fazladır, ancak diğer tüm işlemlerde zaman tasarrufu sağlar. Ayrıca, denemekten daha fazla alan verimlidir.


-2

Bazı (genellikle gömülü, gerçek zamanlı) uygulamalar, işlem süresinin verilerden bağımsız olmasını gerektirir. Bu durumda, bir karma tablosu bilinen bir yürütme süresini garanti ederken, bir üçlü veriye göre değişir.


6
Çoğu hash tablosu bilinen bir yürütme süresini garanti etmez - her eleman çarpışıp zincirlenirse en kötü durum O (n) 'dir
Adam Rosenfield

2
Herhangi bir veri kümesi için, o veri için O (1) aramalarını garanti edecek mükemmel bir karma işlevi hesaplayabilirsiniz. Tabii ki, mükemmel karmayı hesaplamak ücretsiz değil.
George V. Reilly

5
Ayrıca, çarpışmalarla baş etmenin tek yolu zincirleme değildir; bununla ilgilenmek için her türlü ilginç, akıllı yollar vardır - biri için guguk karma ( en.wikipedia.org/wiki/Cuckoo_hashing ) - ve en iyi seçim müşteri kodunun gereksinimlerine bağlıdır.
Hank Gay

guguklu karma ve çiçek filtresi ile ilişkisi hakkında bilmiyordum, ilginç bir okuma yapacak, teşekkürler!
Horia Toma

Önbellek ve varyans için üstün olan Robin-hood Hashing'i unutmayın. sebastiansylvan.com/2013/05/08/… codecapsule.com/2013/11/11/robin-hood-hashing
Jarred Nicholls
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.