web-dev-qa-db-ja.com

地図データ構造を使用する利点は何ですか?

私はいくつかのオンラインコーディングWebサイトのメンバーであり、今日C++でソリューションを提出したとき、C++自体の方がはるかに短い時間でより良い答えがあることがわかりました。ソリューションはオープンだったので、私はそれらのいくつかを調べて、マップデータ構造を使用してそれらすべてを見つけました。エッジが正確にどこにあるかわかりませんでした。私はいくつかグーグルを作りましたが、それは説得力がありませんでした。助けてください。

5
user841923

map はかなりよく丸められた辞書型のコンテナであり、 _std::list_ (リンクされたリスト)および _std::vector_ (配列)。厳密には指定されていませんが、マップに必要なパフォーマンスの制約により、ある種の自己均衡バイナリツリーとして実装することが強制されます。したがって、これらの用語でそれを考えることが役立つ場合は、通常の配列/リンクされたリストよりもバイナリツリーの利点を考慮してください。

ルックアップ時間

キー(データの検索に使用しているもの)が非常に狭い整数の範囲に含まれていることがわかっている場合は、検索(配列のみ)が理想的です。煩わしさのない一定の時間でキーを使って検索できます。

これは、キースペースが大きくなりすぎたり、整数ではない場合に機能しなくなります。明らかに、大量のメモリを無駄にせずに、0番目のスロットと2 ^ 32スポットにのみアイテムが格納されている配列を作成することはできません。マップを使用すると、妥当なルックアップパフォーマンス(O(log(n)))を維持できますが、メモリを格納するのに2スポットしかかかりません。また、マップを使用すると、_< operator_を定義する、またはテンプレート引数を通じてキーを比較する方法をマップに指定する任意の型を検索できます。したがって、文字列のマップ->別の値を適切に検索できます。したがって、マップでは、たとえば_map["Bob"] = 5;_を実行できます。

注文済み

マップは、キーの順序でアイテムを格納します。したがって、ソートされたキーの順序で、マップ内のすべてのアイテムを最初から最後まで反復できます。明らかに配列/ベクトルを使用してこれを行うことができますが、前述のとおり、マップを使用すると、任意の順序を定義した任意のキータイプを定義できます。

挿入

配列/ベクトルの中央に挿入するには、すべてのアイテムを左にシフトする必要があります。動的配列とベクトルの場合は、ベクトルのサイズを変更する必要があります。これにより、配列全体が新しいメモリにコピーされます。

マップには、適切な挿入時間_(O(log(n)))_があります。

異なるトレードオフのある代替案

  • multimapはマップに似ていますが、キーを一意にできません
  • _unordered_map_は、アイテムを順番に格納しないマップですが、適切なハッシュ関数が提供されている場合、より優れた検索パフォーマンスを提供できます。
14
Doug T.

ほとんどの目的で、標準ライブラリのクラスは、作成するデータ構造/コンテナ/アルゴリズムをまとめてすぐに上回ります。これは、正しい抽象化を選択することを前提としています(たとえば、std :: vectorとstd :: listには異なるトレードオフがあります)。ライブラリの一般的な性質を考えると、多くの賢い人々による多くの時間と努力が、これらのライブラリを一般的かつ可能な限り高速にすることに費やされてきました。

非常によく知っている非常に具体的なケースがあり、標準ライブラリクラスも非常によく知っている場合、特定の限定された目的に相当する最高の標準同等物よりも優れたカスタムクラスを作成できるかもしれませんが、そのようなことアプリケーションのプロファイリングがそのような最適化の必要性を示している場合にのみ実行してください。

3