2010-11-06 27 views
11

Bunu nasıl yapacağını ve sözde kodun nasıl görüneceğini bilen var mı?İki diziyle Karma Tablo oluşturma

Hepimiz bir hash tablosunun anahtar, değer çiftlerini depoladığını ve bir anahtar arandığını bildiğimiz gibi, işlev bu tuşla ilişkili değeri döndürecektir. Yapmak istediğim, bu haritalama işlevini oluştururken temel yapıyı anlamak. Örneğin, diziler dışında önceden tanımlanmış işlevlerin olmadığı bir dünyada yaşıyorsak, bugün sahip olduğumuz Hashmaps'i nasıl kopyalayabiliriz?

+3

biraz daha hassas olabilir mi? Tam olarak ne elde etmek istiyorsun? Belirli bir dili mi hedefliyorsunuz değil mi? – romaintaz

+0

@romaintaz açıklama için lütfen yukarıyı inceleyin. – locoboy

cevap

17

Aslında HashMap Protestanlar'ın değil aslında diziler yapılmış olan günümüzün bazı önerdiğiniz gibi. Bunun nasıl çalıştığını bana eskiz edelim:

Hash Fonksiyonu bir hash fonksiyonu birinci dizinin (dizi K) için bir dizin içine anahtarlarınızı dönüştürür. Bunun için genellikle bir modulo operatörü içeren MD5 veya daha basit olan bir karma işlevi kullanılabilir.

Kovalar Basit bir dizi tabanlı Hashmap uygulaması, toplamalarla başa çıkmak için kovalar kullanabilir. K dizisindeki her eleman ('kova'), kendisini çiftlerin bir dizisini (dizi P) içerir. Bir eleman eklerken veya sorguladığınızda, hash fonksiyonu sizi istediğiniz diziyi P içeren K içinde doğru kepçeye yönlendirir. Daha sonra, eşleşen bir anahtar bulana kadar P elemanlarını tekrarlayın veya yeni bir eleman atarsınız. Hash kullanarak kovalara Haritalama tuşları

P.

sonu Sen kovalar sayısı (yani K boyutu) 2'in üssü olduğundan emin olmak gerekir, en 2^b diyelim. Bazı anahtar için doğru kepçe dizinini bulmak için, Hash (anahtar) bilgisini hesaplayın, ancak ilk b bitlerini saklayın. Bu bir tam sayıya yayınlandığında dizininiz.

Yeniden boyutlandırma Anahtarın karmasını hesaplamak ve doğru kepçeyi bulmak çok hızlıdır. Ancak bir kova bir kez dolduğunda, doğru olana ulaşmadan önce daha fazla öğe tekrarlamak zorunda kalacaksınız. Bu yüzden, nesneleri düzgün bir şekilde dağıtmak için yeterli kovanın olması önemlidir veya Hashmap'iniz yavaşlar.

Genellikle Hashmap'te ne kadar nesne saklamak isteyeceğinizi bilmediğinizden, haritayı dinamik olarak büyütmek veya küçültmek tercih edilir. Depolanan nesne sayısının bir miktarını tutabilirsiniz ve belirli bir eşiğin üzerine düştüğünde, tüm yapıyı yeniden oluşturursunuz, ancak bu sefer dizi K için daha büyük veya daha küçük boyutludur.Bu şekilde, K'daki tam dolu kovaların bazıları, artık elemanlarının birkaç kovaya bölünmesini sağlayacak, böylece performans daha iyi olacak.

Alternatifler Ayrıca, bir dizi-of-the diziler yerine iki boyutlu bir dizi kullanabilir veya bağlantılı bir liste için dizi P değiştirebilir. Ayrıca, depolanmış nesnelerin toplam sayısını tutmak yerine, kovalardan biri yapılandırılmış sayıda öğeden daha fazlasını içerdiğinde, hashmap'ı yeniden oluşturmayı (yani, yeniden boyutlandırmayı) seçebilirsiniz.

Sorduğunuz şeyin bir varyasyonu, Hash table Wikipedia entry'da 'dizi karma tablosu' olarak tanımlanır.

Kod Kod örnekleri için here'a bakın.

Bu yardımcı olur umarım.

-1

Daha kesin misiniz? Bir dizide anahtarlar, diğeri de değerler var mı? Eğer öyleyse

, burada Java örneğidir (ancak bu dilin birkaç özgüllükleri burada vardır): Tabii

for (int i = 0; i < keysArray.length; i++) { 
    map.put(keysArray[i], valuesArray[i]); 
} 

, Java kullanıyorsanız, (sizin map nesne örneğini zorunda kalacak, null nesnesini önlemek için dizilerinizi sınayın ve aynı boyuta sahip olup olmadıklarını kontrol etmek için dizilerinizi sınayın (HashTable yerine HashMap<Object, Object> kullanın).

+0

Java kullanacağını söylemedi, ama yine de iyi bir tavsiye. –

+0

Evet, aslında onu görmedim. Cevabımı düzenledim, ancak ana kısım Java'ya özgü değil. – romaintaz

+4

Eminim ki iki dizi kullanarak bir hash tablosunun kendi uygulamasını yaratmak istiyor. – sepp2k

-1

Bunu mu demek istediniz?

bir örnek olarak Ruby'nin irb kullanıyor aşağıdadır:

cities = ["LA", "SF", "NY"] 
=> ["LA", "SF", "NY"] 

items = ["Big Mac", "Hot Fudge Sundae"] 
=> ["Big Mac", "Hot Fudge Sundae"] 

price = {} 
=> {} 

price[[cities[0], items[1]]] = 1.29 
=> 1.29 

price 
=> {["LA", "Hot Fudge Sundae"]=>1.29} 

price[[cities[0], items[0]]] = 2.49 
=> 2.49 

price[[cities[1], items[0]]] = 2.99 
=> 2.99 

price 
=> {["LA", "Hot Fudge Sundae"]=>1.29, ["LA", "Big Mac"]=>2.49, ["SF", "Big Mac"]=>2.99} 

price[["LA", "Big Mac"]] 
=> 2.49 
+2

teşekkürler, ancak karma işlevini tam olarak nerede tanımlıyorsunuz? Bildiğim kadarıyla bir karma işlevi, iki dizi ve çarpışmalardan kurtulmanın bir yoluna ihtiyacınız var. – locoboy

0

Numune Açıklama:

1. Harita Temsil

  • Bazı (Listesi'nin X sayısı) listelerini
  • : Aşağıdaki Kaynakta

    , temelde iki şey yapar X 2 güç N sayıda liste kötüdür. A (2 güç N) -1 veya (2 güç N) + 1 veya bir asal sayı iyidir.

Örnek:

List myhashmap [hash_table_size]; 
// an array of (short) lists 
// if its long lists, then there are more collisions 

NOT: şudur dizinin dizi değil, iki diziler (Sadece 2 dizilerle iyi bir şekilde, olası jenerik hashmap göremez)

Algoritmalar> Grafik teorisi> Komşuluk listesini biliyorsanız, bu tam olarak aynı görünüyor.

2.Hash fonksiyonu

ve hızlı arama fonksiyonu (sonra int dönüştürülür)

  • ilk karakter karma değeri başlatmak

    bir dizi indeksi olan bir sayı (müzakere değeri) dizesi (giriş) dönüştürür
  • vites değiştirme 4 bit, daha sonra kömürü ilave kalan her birinin ayrıca char
  • ,

Örnek sonra (int dönüştürülür)

int hash = input[0]; 
for (int i=1; i<input.length(); i++) { 
    hash = (hash << 4) + input[i] 
} 

hash = hash % list.size() 
// list.size() here represents 1st dimension of (list of lists) 
//  that is 1st dimension size of our map representation from point #1 
//  which is hash_table_size 

ilk bağlantıda bakınız:

int HTable::hash (char const * str) const 

Kaynak:
http://www.relisoft.com/book/lang/pointer/8hash.html
How does a hash table work?

Güncelleme
Bu Best kaynağıdır: http://algs4.cs.princeton.edu/34hash/