2016-10-26 8 views
0

C言語を学ぶために、おそらくForthのような意味での単純なオブジェクトシステムを設計しています。私が設計したデータ構造の1つはハッシュテーブル、つまりhash_tです。私はPython 3.6's dictionariesのこの説明の私の理解の下でそれを実装しましたあまりメモリを使用しないハッシュテーブルを設計するにはどうすればよいですか?

typedef struct { 
    array_t* keys;  // intelligent array object 
    assoc_t* vals;  // array<pair> 

    ssize_t* idxs;  // raw C array 
    size_t idxs_len; // and its length 

} hash_t; 

a hashtable consists of: 
    non-sparse array_t of keys 
    non-sparse associative array of pairs of values and their key's hashes 
    sparse raw array of which values map to which actual entries. 

    { 1: 'a', 2: 'b', 3: 'c' } 

    is represented in this structure as: 

    hash->keys = array{ 1, 2, 3 } 
    hash->vals = assoc{ 
    pair{ 'a' 5 } 
    pair{ 'b' 7 } 
    pair{ 'c' 9 } 
    } 
    hash->idxs = array{ -1 -1 -1 -1 -1 0 -1 1 -1 2 -1 } 
            ^ ^ ^
             5  7  9 

    where 5, 7, and 9 are the hashes of 1, 2, and 3. 

-1は存在しない値を示すために、PythonのポストにNoneの代わりをします。

私の鍵1(文字列化された)が0x340ca71cまたは873,244,444にハッシュされているときに問題が発生します。したがって、キーの配列(hash->idxs)は、sizeof (ssize_t) * (873,244,444 + 1)、または8 * 873,244,444 = 6,985,955,552バイト、または私のラップトップよりも多くのRAMである必要があります。また、より多くのRAMをより1つハッシュテーブルが必要になります。

私がPythonで作成する各辞書は、何百万バイトものRAMも必要としませんが、C言語でこのように実装されているようです。何が欠けていますか?

+1

閲覧:https://en.m.wikipedia.org/wiki/Hash_table – hyde

答えて

1

ハッシュに含めるアイテムの数に基づいてハッシュ数を決定し、ハッシュ範囲をその範囲に減らします。

バケツごとに約10個のアイテムを含む約100,000個のアイテムを保持するには、約10,000個のバケットが必要です。したがって、ハッシュを計算した後、10,000を法とするハッシュを取って、アイテムを入れるバケットを決定してください。

一般的に、バケットカウントの素数を使うと最も効果的です。

+1

バケットあたり10個のアイテム、負荷係数10は非常に高いようです...いくつかの用途では正当な可能性があります汎用用途に使用します。 – hyde

+0

私は、要素の数が変化するにつれてバケツの数を変えるコードを記述するのに苦労したくないと思っています。これは、テーブルに多くの要素がある場合の負荷係数が高い場合と、非常に少ない場合に無駄なメモリとの間で妥協を強いられます。 –

+0

負荷係数を決定し、それを超えたときに大きなバケットカウントで再ハッシュするのが一般的ではありませんか。いずれにしても、バケットは動的である必要があります。また、大部分の(またはすべての)アイテムを1つのバケットに入れる最悪の入力(意図的に作成された可能性があります)には戦略が必要です。 – hyde

関連する問題