Map 和 Set 容器

 

Map和Set 所谓 关联容器 Associative Container 与顺序容器(Sequential Container)的本质区别在于:

 

关联容器是通过键(key)存储和读取元素的,而顺序容器则通过元素在容器中的位置顺序存储和访问元素。

 

map的元素是“键-值”对的二元组形式:键用作元素在map中的索引,而值 则表示所存储和读取的数据。

set的元素包含一个键,并有效地支持关于某个键是否存在的查询。

map 关联数组:元素通过键来存储和读取
set   大小可变的集合,支持通过键实现的快速读取
multimap 支持同一个键多次出现的map类型
multiset 支持同一个键多次出现的set类型

 

set和multiset容器的能力
set和multiset容器的内部结构通常由平衡二叉树(balanced binary tree)来实现。当元素放入容器中时,会按照一定的排序法则自动排序,默认是按照less<>排序规则来排序。这种自动排序的特性加速了元素查找的过程,但是也带来了一个问题:不可以直接修改set或multiset容器中的元素值,因为这样做就可能违反了元素自动排序的规则。如果你希望修改一个元素的值,必须先删除原有的元素,再插入新的元素。

查找元素
    在map和set容器中,元素是有序存储的(升序),同样multimap和multiset也一样。因此,在multimap和multiset容器中,如果某个键对应多个实例,则这些实例在容器中将相邻存放,即迭代遍历时,可保证依次返回特定键所关联的所有元素。
    要查找特定键所有相关联的值,可以有下面三种方法:
    1)配合使用find和count来查找:count函数求出某键出现的次数,而find操作返回指向第一个键的实例的迭代器。
    2)使用lower_bound和upper_bound函数:这两个函数常用于multimap和multiset,但也可以用于map和set容器。所有这些操作都需要传递一个键,并返回一个迭代器。
m.lower_bound(k) 返回一个迭代器,指向键不小于k的第一个元素
m.upper_bound(k) 返回一个迭代器,指向键大于k的第一个元素
m.equal_range(k) 返回一个迭代器的pair对象

                              它的first成员等价于m.lower_bound(k),而second成员则等价于m.upper_bound(k)

注意:形成的有效区间是[lower_bound(k), upper_bound(i)),是个半开半闭区间。

 

//测试 Map容器

void TestMap()

{

 typedef map<int, string> UDT_MAP_INT_CSTRING; //定义类型

 

 map<int,string> M;
 
 M[1] = "One";//该插入方法效率不高
 M.insert(map<int, string> :: value_type(2, "Two"));//建议使用该插入方法
 M.insert(make_pair(11,"A"));

 int nFindKey = 2; //要查找的Key
 UDT_MAP_INT_CSTRING::iterator pItFind = M.find(nFindKey);
 if (pItFind == M.end())
 {
  cout << "not found" << endl;
 }
 else
 {
  if (pItFind->first)//first对应key, second对应value
   cout << pItFind->second.c_str() << endl;
 }

 for(map<int,string>::iterator pIt=M.begin(); pIt!=M.end(); pIt++)
 {
  if (pIt->first)
   cout << pIt->second.c_str();
 }
 cout << endl;

 M.erase(1);//删除key为1的元素
 for(map<int,string>::iterator pIt=M.begin(); pIt!=M.end(); pIt++)
 {
  if (pIt->first)
   cout << pIt->second.c_str();
 }
 cout << endl;

 M.erase(pItFind);//删除迭代器指向的元素
 for(map<int,string>::iterator pIt=M.begin(); pIt!=M.end(); pIt++)
 {
  if (pIt->first)
   cout << pIt->second.c_str();
 }
 cout << endl;

}

 

Output:

Two
OneTwoA
TwoA
A

 

//测试 Multiset容器

void TestMultiset()
{
 cout << "TestMultiset" << endl;

 const int N = 5;
 int a[N] = {4,1,1,3,5};
 multiset<int> A(a,a+N);//使用数组初始化容器,multiset容器 升序排序
 copy(A.begin(),A.end(),ostream_iterator<int>(cout," "));
 cout << endl;
}

 

Output:

TestMultiset
1 1 3 4 5

 

//测试 Multiset容器

void TestMultiset2()
{
 cout << "TestMultiset" << endl;

 multiset <int>::iterator ms1_Iter, ms2_Iter, ms3_Iter;
   multiset <int>::iterator ms4_Iter, ms5_Iter, ms6_Iter;

   // Create an empty multiset ms0 of key type integer
   multiset <int> ms0;

   // Create an empty multiset ms1 with the key comparison
   // function of less than, then insert 4 elements
   multiset <int, less<int> > ms1; //升序存储
   ms1.insert( 10 );
   ms1.insert( 20 );
   ms1.insert( 20 );
   ms1.insert( 40 );
   ms1.insert( 4 );

   // Create an empty multiset ms2 with the key comparison
   // function of geater than, then insert 2 elements
   multiset <int, greater<int> > ms2;//降序存储
   ms2.insert( 10 );
   ms2.insert( 20 );
   ms2.insert( 2 );

   // Create a multiset ms3 with the
   // allocator of multiset ms1
   multiset <int>::allocator_type ms1_Alloc;
   ms1_Alloc = ms1.get_allocator( );
   multiset <int> ms3( less<int>(), ms1_Alloc );
   ms3.insert( 30 );

   // Create a copy, multiset ms4, of multiset ms1
   multiset <int> ms4( ms1 );

   // Create a multiset ms5 by copying the range ms1[_First, _Last)
   multiset <int>::const_iterator ms1_bcIter, ms1_ecIter;
   ms1_bcIter = ms1.begin( );
   ms1_ecIter = ms1.begin( );
   ms1_ecIter++;
   ms1_ecIter++;
   multiset <int> ms5( ms1_bcIter, ms1_ecIter );

   // Create a multiset ms6 by copying the range ms4[_First, _Last)
   // and with the allocator of multiset ms2
   multiset <int>::allocator_type ms2_Alloc;
   ms2_Alloc = ms2.get_allocator( );
   multiset <int> ms6( ms4.begin( ), ++ms4.begin( ), less<int>( ), ms2_Alloc );

   cout << "ms1 =";
   for ( ms1_Iter = ms1.begin( ); ms1_Iter != ms1.end( ); ms1_Iter++ )
      cout << " " << *ms1_Iter;
   cout << endl;
   //当multiset容器降序 ms2_Iter=ms2.begin();报错
   cout << "ms2 = " << *ms2.begin( ) << " " << *++ms2.begin( )
   << endl;

   cout << "ms3 =";
   for ( ms3_Iter = ms3.begin( ); ms3_Iter != ms3.end( ); ms3_Iter++ )
      cout << " " << *ms3_Iter;
   cout << endl;

   cout << "ms4 =";
   for ( ms4_Iter = ms4.begin( ); ms4_Iter != ms4.end( ); ms4_Iter++ )
      cout << " " << *ms4_Iter;
   cout << endl;

   cout << "ms5 =";
   for ( ms5_Iter = ms5.begin( ); ms5_Iter != ms5.end( ); ms5_Iter++ )
      cout << " " << *ms5_Iter;
   cout << endl;

   cout << "ms6 =";
   for ( ms6_Iter = ms6.begin( ); ms6_Iter != ms6.end( ); ms6_Iter++ )
      cout << " " << *ms6_Iter;
   cout << endl;

}

 

Output:
TestMultiset
ms1 = 4 10 20 20 40
ms2 = 20 10
ms3 = 30
ms4 = 4 10 20 20 40
ms5 = 4 10
ms6 = 4

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值