web-dev-qa-db-ja.com

C ++のset <pair>とmapの違いは何ですか?

C++ STLでキーと値の属性を簡単に作成するには、マップとペアのセットの2つの方法があります。たとえば、私は持っているかもしれません

map<key_class,value_class>

または

set<pair<key_class,value_class> >

アルゴリズムの複雑さとコーディングスタイルの観点から、これらの使用法の違いは何ですか?

28
Luís Guilherme

セット要素は、セット内にある間は変更できません。 setiteratorconst_iteratorは同等です。したがって、set<pair<key_class,value_class> >では、value_classをインプレースで変更できません。セットから古い値を削除し、新しい値を追加する必要があります。ただし、value_classがポインターの場合、これが指すオブジェクトを変更することを妨げるものではありません。

map<key_class,value_class>を使用すると、マップへの非const参照があると想定して、value_classをインプレースで変更できます。

31
bk1e

それらは意味的に異なります。検討してください:

#include <set>
#include <map>
#include <utility>
#include <iostream>

using namespace std;

int main() {
  pair<int, int> p1(1, 1);
  pair<int, int> p2(1, 2);
  set< pair<int, int> > s;
  s.insert(p1);
  s.insert(p2);
  map<int, int> m;
  m.insert(p1);
  m.insert(p2);
  cout << "Set size = " << s.size() << endl;
  cout << "Map size = " << m.size() << endl;
}

http://ideone.com/cZ8Vjr

出力:

セットサイズ= 2
マップサイズ= 1

43
Philipp

基本的な違いは、セットの場合、キーはペアであるのに対し、マップの場合、キーはkey_classであるということです。これにより、マップで行いたいことであるkey_classによる検索が困難になります。

どちらも通常は同じデータ構造(通常は赤と黒のバランスのとれたバイナリツリー)で実装されるため、2つの複雑さは同じです。

8
anon

map<key_class,value_class>はkey_classでソートし、key_classの重複を許可しません。
set<pair<key_class,value_class> >は、key_classのインスタンスが等しい場合、key_class、次にvalue_classでソートし、key_classに複数の値を許可します

8
Jherico

std::mapは、連想データ構造として機能します。つまり、関連付けられたキーを使用して値をクエリおよび変更できます。

std::set<pair<K,V> >はそのように機能させることができますが、キーを使用してクエリの追加コードを記述し、値を変更するコードを追加する必要があります(つまり、古いペアを削除して、同じキーと別のペアを挿入します)値)。また、同じキーを持つ値が2つ以下であることを確認する必要があります(推測したとおり、コードが増えます)。

つまり、std::setstd::mapのように動作させることができますが、その理由はありません。

2
MAK

アルゴリズムの複雑さを理解するには、最初に実装を理解する必要があります。

std :: mapはRBツリーを使用して実装されますが、hash_mapはリンクリストの配列を使用して実装されます。 std :: mapは、挿入/削除/検索操作にO(log(n))を提供し、hash_mapはO(1)が最良のケースであり、o(n)ハッシュの衝突に応じて最悪の場合。

1
Sach

コードをステップ実行した後にPhilippが述べた意味の違いを視覚化して、マップキーがどのようにconst intであり、どのようにp2がmに挿入されなかったかに注意してください。

enter image description here

1
Alan