2009-04-09 14 views
10

関心領域は文字列一致です。このような構造があるとします。完全なハッシュ関数を設計するにはどうしたらいいですか?

typedef struct 
{ 
    char *name, 
    int (*function)(); 

} StringArray 

StringArray s[] = 
{ 
    {"George", func1}, 
    {"Paul", func2}, 
    {"Ringo", func3}, 
    {"John", func4}, 
    {"",  NULL} /* End of list */ 
} 

配列には固定数の文字列があります。これらは例のようにハードコードされています。 テーブルが変更された場合、ハッシュ関数の品質を再評価する必要があります。

文字列にハッシュ関数を適用し、文字列が配列に一致する場合は、 関数を呼び出します。これには完全なハッシュ関数が必要です。衝突は許されません。ハッシュを要求する目的は、ルックアップでO(1)のパフォーマンスを得ることです。

これを行うための機能を設計するためにどのようなアイデアがありますか?

+0

悪私はスパムがあなたはそれが –

+0

@Mitchを意味考えるものを意味しないと思う:あなたはこれを意味するか簡単にするためにGoogleで検索することができ、質問ありますか? –

+0

@ j_random_hacker:しました。しかし、それは遅く、スパムではありません。 –

答えて

16

gperfホーム・ページを参照してくださいを使用することができます。

+0

ギャルの部分は、ウィキペディアのページの下部にこれへのリンクがあるということです。 – EvilTeach

0

あなたはマップ

std::string foo() { return "Foo"; } 
std::string bar() { return "Bar"; } 

int main() 
{ 
    std::map<std::string, std::string (*)()> m; 
    m["foo"] = &foo; 
    m["bar"] = &bar; 
} 
+0

std ::マップはハッシュを使用しません - それは木をベースにしています –

+0

なぜホイールを発明するには、マップのような既存のライブラリを使用することができます。 – Vinay

+1

おそらく質問者は、木の検索よりもハッシングのパフォーマンス特性を望んでいたでしょうか? –

1
+0

質問に直接は触れませんが、とにかく良いリンクです。 – EvilTeach

+0

downvoter(この非常に古い質問に)コメントを残してください。ありがとう。 –

0

衝突が絶対に許可されていない場合は、あなたの唯一のオプションは、おそらくへの最善の方法ではありませんデータベースにすべての文字列を追跡することです行く。

私が行うことは、MD5やSHAなどの既存の一般的な強力なハッシュアルゴリズムの1つを適用することです。サンプルの周りにはすべてのサンプルがあります。例:http://www.codeproject.com/KB/security/cryptest.aspx

-1

まあ、完璧なハッシュ関数はありません。

衝突を最小限に抑えるものがいくつかありますが、衝突を最小限に抑えるものはありません。

はしかし1に助言することはできません:P

EDIT:ソリューションは完璧なハッシュ関数を見つけることができません 。解決策は、衝突を認識することです。一般に、ハッシュ関数には衝突があります。明らかに、データセットと生成されるハッシュコードのサイズに依存します。

+0

http://en.wikipedia.org/wiki/Perfect_hashing –

+0

@Adam:個別のデータセットがある場合にのみ適用されるという点でかなり大きな警告があります。 OPが使用されている文字列を制限することについて何の言及もしていないので、私はこの場合完全なハッシュがないことをMegacanに同意するでしょう。 +1。 – sipwiz

+0

質問者は、彼らが解凍したドラマーとStu whatsisnameを含めると、少なくとも暗黙のうちに - ビートルズは4つしかない)またはサイズを言います - それでも、固定データセットです。 –

0

バランスのとれたバイナリツリーを使用します。その後、あなたはノウエフの動作は常にO(ログ)です。

私はハッシュを強く嫌っています。人々は彼らのアルゴリズムでどれくらいのリスクを冒すか分かりません。彼らはいくつかのテストデータを実行し、次にフィールドに展開します。私は、配備されたハッシュアルゴリズムがフィールドの動作をチェックするのを決して見たことはありません。

O(log n)は、O(1)の代わりにほぼ常に許容されます。

+0

"O(log n)は、ほとんど常にO(1)の代わりに受け入れられます。"多くのアプリケーションで、この文は間違っています。これを見るには、データポイントの数を数百万以上に増やしてください。 –

+0

これを済ませたら、テストしてください。可能なすべての入力が可能であることを事前に知っていない限り、ハッシュは保証された結果を提供しません。入力を集める傾向のあるハッシュ関数は、おそらくO(1)を与えません。 –

+0

この場合、すべての入力がわかります。彼らは配列に座っている。 であり、入力文字列は完全一致または不一致のいずれかです。 – EvilTeach

2

概要では、CとC++の両方が一覧表示されます。あなたはどちらをお探しですか? CとC++は2つの異なる言語であり、文字列の扱いやデータ構造が大きく異なります(C++で動作するものはそれを変更しません)。

なぜ、具体的には、完全なハッシュ関数が必要ですか?文字列を関数に関連づけたいのですが、それを行うには良い方法だろうと思いますか?これはある種の宿題ですか?マップ<>をC++で使用しない理由がありますか? (または、unordered_map <が利用可能であれば)

完全なハッシュが必要な場合は、文字列の制約は何ですか?ディスパッチしたい固定セットがありますか?セットの1つに一致しない文字列はどうですか?ランダムな文字列からのヒットを受け入れるのですか、または入力文字列の数が制限されていますか?

質問を編集してそのような情報を含めることができれば、より多くの役に立ちます。 (最初の2つのコメントに応答して)

EDIT:あなたはおそらくあなたのCおよびC++の仕事の両方のためにこれをしたいので、

OK、我々は、Cのソリューションをご覧ください。あなたはおそらくパフォーマンスを望んでいますが、テストしましたか?私たちがI/Oシステムに入ってくる文字列を処理している場合、ディスパッチ時間を矮小化する可能性があります。

任意の文字列が必要です。ランダムなデータからのすべての衝突を避ける完璧なハッシュ関数を期待するのはちょっとですから、それを考慮する必要があります。

trieとお考えですか?それは完全なハッシュ関数よりも効率的であるかもしれませんし、そうでないかもしれません.Cで実装するのはかなり簡単で、ディスパッチ文字列や衝突の可能性のあるリストをやり直す際の問題を避けます。

+0

私はcとC++の両方でコードし、神はPro * Cを助けます。 パフォーマンスのためにO(1)ハッシュ。 笑、宿題なし。私はいくつかのパフォーマンスクリティカルなコードをスピードアップするツールを構築しようとしています。この例は、議論の目的で単純化されている。現実世界の使用はそうではありません。 – EvilTeach

+0

文字列の長さは非常に長くなります。いずれも長さゼロではありません。 実際の制限として、配列内の文字列は32文字より長くなりません。呼び出し元が渡すものは任意の長さにすることができますが、テーブルの文字列よりも長い場合は、トライに言及するためにno-match – EvilTeach

+0

+1の場合があります。 –

0

この演習の最終結果は、ネットオフの文字列指向のハッシュ関数の数を盗む

    • にしました。
    • 一連のファクト・クラスを作成し、各ファンクションを、そのファンクションで動作する最小の完全なハッシュを探して、一連のmod演算子値を持つデータ・セットに対してテストしました。
    • その工場クラスのデフォルトのコンストラクタは、文字列を返します。文字列は、使用時に正しいハッシュ関数を選択する引数の集合を表し、最小サイズのメモリを必要とする完全なハッシュを与えるためのサイズです。
    • 通常の使用では、返された引数を使用してクラスをインスタンス化するだけで、クラスは目的の関数を持つ動作状態になります。
    • そのコンストラクタは、衝突がないことを検証し、衝突があれば中止します。
    • 完全なハッシュが見つからない場合、ソートされたバージョンの入力テーブルをバイナリ検索に分解します。

    私のドメインにある配列のセットについては、これは非常にうまくいくようです。 将来可能な最適化は、入力の部分文字列に対して同じ種類のテストを行うことです。サンプルの場合、各ミュージシャンの名前の最初の文字は、それらを区別するのに十分です。次に、実際のハッシュ関数のコストを と比較する必要があります。

    アイデアを寄稿したすべての人に感謝します。