2012-02-21 19 views
0

問題:ユーザーID(整数)を指定すると、ユーザーが属するグループをすばやく見つけることができます。グループには15人以下のユーザーが含まれます。さらに、私は読み込みI/Oイベントに渡されるパラメータを制御できないlibevを使用しているので、userID(ファイル記述子/整数)は実際にはのものだけです。配列内の整数を見つける最も速い方法は何ですか?

私の解決策: groupIDとuserIDのペアを含むハッシュテーブルにユーザーIDを一度ハッシュします。 groupIDを2回ハッシュし、groupIDと15個のuserIDのペアの配列を含むハッシュテーブルにハッシュします。

解決策は機能しますが、これは不本意ながら実行されるサーバーコードです。二重ハッシングが非効率的で、より良い解決策があるかどうかは疑問です。

+2

http://codereview.stackexchange.com/で使用している実際のコードを投稿するとよいでしょう。 –

+0

なぜ誰かが私が求めているものとは異なる質問に投稿のタイトルを変更したのかよく分かりません。 –

答えて

0

グループの配列でuserIDをソートし、バイナリ検索アルゴリズムを使用します。

groupidで同じことを行い、groupIDとユーザーIDの配列を含むクラスまたは構造体を作成します。

あなたのグループの配列を作成し、それらを追加するときに並べ替えるよりも、バイナリ検索アルゴリズムを再度使用してグループを検索してください。


編集:「ハッシュマップは、」常にデータ増加のあなたの量と同じ時間がかかりますしながら、

バイナリ検索は少量のデータのために良いかもしれません。

だからここ2つのソリューションの比較で別の質問へのリンクです:私はあなたが正しかったことを認めなければならないWhich is faster, Hash lookup or Binary search?

+0

よく構築されたハッシュテーブルは一定のルックアップ時間を持ちます。バイナリ検索アルゴリズムはO(log n)の検索時間を持ちます。並べ替えを維持するために配列を常に更新することに伴うオーバーヘッドについては言及しません。私はこの方法について何が良いのか混乱していますか? –

+0

私は専門家ではありませんが、2つの解の複雑さを見てみました。そして、最悪の場合、ハッシュマップはO(n)である傾向があり、バイナリ検索は常にO(logn)です。ソートの時間は、グループやユーザーをたくさん追加しないと問題ではないかもしれません。 –

+0

最悪の場合、ハッシュテーブルがO(n)であるのは当然ですが、あまりうまく設計されていないハッシュテーブルだけがそのように動作するはずです。私はintをハッシュしているだけなので、衝突の少ないハッシュを設計するのは簡単なはずです。また、私は何千人ものユーザーと数百のグループを管理します。 –

1

あなたは、libevには限られた量のデータしか与えられていないと言いますが、ev_ioはそれ自身を処理し、そこにはファイル記述子がすべて有益であると結論づけています。まあ、普通、あなたはおそらく正しいでしょうが、あなたができることはきちんとしたトリックがあります。

libevでは構造体を自分で割り当ててからlibevで初期化するので、を割り当てすぎることはありませんスペースです。 libevは余分なスペースに触れないので、そこにあなた自身のものを置くことができます。成功!

これは実際にどのように機能しますか?あなたが最初のメンバーとしてev_ioを含む新しい構造体を作成し、それの後にあなたのデータのすべての残りの部分を入れて、次のように言う:あなたはuv_ioを割り当てるどこ

struct my_mutant_io { 
    ev_io handle; 
    int group_id; 
}; 

が、代わりにmy_mutant_ioを割り当てます。あなたが好きしかし、そこにデータを入れて、あなたがlibuv関数にそれを渡す必要があります一度、だけではなく、handleのアドレス取る:

struct my_mutant_io *mutant = malloc(sizeof(struct my_mutant_io)); 
if(!mutant) { 
    abort(); 
} 
mutant->group_id = /* ... */; 
ev_io_init(&mutant, some_callback, fd, EV_READ); 

あなたはev_io libevは与えてくれたが、それはどれも、ですそれは実際にはより大きな構造体の一部に過ぎません。次に、コールバックに移りましょう。あなたはev_ioを元に戻しますが、待ってください!ev_ioは構造体の最初のメンバーなので、そのアドレスは突然変異体のアドレスと同じです。 ev_io *struct my_mutant_io *にキャストして使用することができます。 (ただ、厳格なエイリアシングの神々を教えていない。)

このような構造体は、最も一般的にバトンと呼ばれています。

関連する問題