set <pair>和C ++中的map有什么区别?</pair>

时间:2010-07-14 16:58:21

标签: c++ data-structures stl map set

我可以通过两种方式轻松地在C ++ STL中创建一个键,值属性:映射和对的集合。例如,我可能有

map<key_class,value_class>

set<pair<key_class,value_class> >

在算法复杂性和编码风格方面,这些用法之间有什么区别?

7 个答案:

答案 0 :(得分:43)

它们语义不同。考虑:

#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

答案 1 :(得分:31)

设置元素在集合中时无法修改。 set的{​​{1}}和iterator是等效的。因此,使用const_iterator时,您无法就地修改set<pair<key_class,value_class> >。您必须从集中删除旧值并添加新值。但是,如果value_class是指针,则不会阻止您修改它指向的对象。

使用value_class,您可以就地修改map<key_class,value_class>,假设您有对地图的非const引用。

答案 2 :(得分:7)

基本区别在于,对于集合,键是对,而对于映射,键是key_class - 这使得通过key_class查找内容,这是您想要对映射执行的操作,对于集合来说很难。 / p>

两者通常使用相同的数据结构(通常是红黑平衡二叉树)实现,因此两者的复杂性应该相同。

答案 3 :(得分:7)

map<key_class,value_class>将对key_class进行排序,并且不允许重复使用key_class 如果key_class实例相等,set<pair<key_class,value_class> >将对key_class和value_class进行排序,并且将允许key_class的多个值

答案 4 :(得分:2)

std::map充当关联数据结构。换句话说,它允许您使用其关联的键查询和修改值。

可以使std::set<pair<K,V> >像这样工作,但你必须使用密钥和更多代码来编写查询的额外代码来修改值(即删除旧对并使用相同的密钥插入另一对和不同的价值)。您还必须确保使用相同的密钥不超过两个值(您猜对了,代码更多)。

换句话说,你可以尝试用std::set来像std::map一样工作,但没有理由。

答案 5 :(得分:1)

要了解算法的复杂性,首先需要了解实现。

std :: map是使用RB-tree实现的,其中hash_map是使用链表的数组实现的。 std :: map为插入/删除/搜索操作提供O(log(n)),hash_map是O(1)是最好的情况,o(n)在最坏的情况下取决于散列冲突。

答案 6 :(得分:1)

在逐步完成代码后,可视化Philipp提到的语义差异,注意map key是一个const int以及p2如何不插入 m

enter image description here