宿題以外では、これにはリレーショナル データベースを使用します。しかし、それはおそらく役に立たないでしょう…</p>
他の人がすでに指摘しているように、最初に把握する必要があるのは、処理しているデータの量です。O( n ) ブルートフォース検索は、 nが小さい限り十分高速です。些細な量のデータはこれを些細な問題にするので (配列に入れて、力ずくで検索するだけです)、データ量が大きいと仮定します。
都市の保存
まず、検索要件には、複数の方法で並べ替えられたデータが必要なようです。
- いくつかの都市の一意の識別子 (名前?)
- 来場者数
これは実際に満足するのはそれほど難しいことではありません。(1)が一番簡単です。都市を配列に格納します。配列インデックスは一意の識別子になります (仮定: 都市を削除しないか、都市を削除する場合は、その配列スポットを未使用のままにして、メモリを浪費します。追加は問題ありません)。
ここで、訪問数が最も多いものと最も少ないものを見つけられるようにする必要もあります。変更 (都市の追加、訪問者数の変更など) が発生し、リレーショナル データベースから借用することを想定して、バランス ツリーの形式を使用してインデックスを作成することをお勧めします。データベースは一般的に B-Tree を使用しますが、別のものがうまくいくかもしれません: check木に関するウィキペディアの記事。各ツリー ノードには、都市データのポインター (または配列インデックス) を保持するだけです。別のコピーを作成する理由はありません。
1 つの単純な理由から、ハッシュよりもツリーをお勧めします。上位または下位の N 個のアイテムを見つけるために、非常に簡単に事前注文または逆注文トラバーサルを実行できます。ハッシュではそれができません。
もちろん、変更が行われない可能性がある場合は、別の配列を使用してください (アイテムへのポインターの、繰り返しますが、それらを複製しないでください)。
プロファイルへの都市のリンク
これを行う方法は、データをクエリする方法と、データの形式によって異なります。最も一般的なのは、各プロファイルを複数の都市に関連付けることができ、各都市を複数のプロファイルに関連付けることができるということです。さらに、どちらの方向からでも効率的にクエリを実行できるようにしたいと考えています。そして「ボブはどの都市を訪れますか?」。
再び恥知らずにデータベースから持ち上げて、別のデータ構造を作成します。これは、次の行に沿ったかなり単純なものです。
struct profile_city {
/* btree pointers here */
size_t profile_idx; /* or use a pointer */
size_t city_idx; /* for both indices */
};
したがって、ボブ (プロファイル 4) がフェニックス (都市 2) を訪れた
profile_idx = 4
としcity_idx = 2
ます。ボブがラスベガス (都市 1) も訪れたと言うには、もう 1 つ追加するので、ボブには 2 つあることになります。
ここで、選択肢があります。これらをツリーまたはハッシュに格納できます。個人的には、そのコードは既に書かれているので、ツリーを使用します。ただし、ルックアップの場合、ハッシュはO(log n ) ではなく O( n )になります。
また、都市の訪問回数で行ったのと同じように、インデックスを作成して
city_idx
、その側からもルックアップを実行できるようにします。
結論
これで、最も訪問された 5 つの都市を検索し (都市訪問カウント インデックスを順番に走査して)、city_idx
インデックス内の各都市を検索して
profile_idx
. ユニークなアイテムだけを手に入れれば、答えが見つかります。
ああ、ここで何かがおかしいようです: これは、インストラクターが数時間で書きたいと思う非常に多くのコードのようです!