STL学习系列之五——关联容器

STL学习系列之五——关联容器

关联容器:

利用键,STL的关联容器能直接保存和提取键。

4个关联容器分别为:multiset,set,multimap,map。每个关联容器都按有序的方式维护者它的键。对关联容器的迭代遍历是根据这个容器的排序顺序进行的。

multiset和set提供了对值的集合的操作,其中的值都是键,每个键并不存在一个关联值。

multimap和map提供了与键相关联的值的操作(这些值有时被称作映射值)。

multiset和set的主要区别是:multiset允许重复的键,set不允许。

multimap和map的主要区别是:multimap允许用重复的键保存关联值,而map允许用唯一的键保存关联值。

1.multiset

multiset关联容器提供了键的快速保存于提取,并允许重复的键。

元素的顺序由比较函数对象确定,e.g.在一个整数multiset中,元素能够通过比较函数对象less<int>按键的升序排序。

multiset支持双向迭代器(而不是随机访问迭代器)

下列demo1演示了一个按升序保存整数的multiset关联容器。

#include <iostream>
#include <set>
#include <algorithm>
#include <iterator>
using namespace std;

typedef multiset<int,less<int>> Ims;

int _tmain(int argc, _TCHAR* argv[])
{
 const int SIZE = 10;
 int a[SIZE]={7,22,9,1,18,30,100,22,85,13};
 Ims intMultiset;
 ostream_iterator<int> output(cout," ");

 //count函数用于计算multiset中当前保存的值15的出现次数
 cout<<"现在这里有"<<intMultiset.count(15)<<"个值15在这个multiset里\n";

 
 //将值15两次添加到multiset中
 intMultiset.insert(15);
 intMultiset.insert(15);
 cout<<"插入后,这里有"<<intMultiset.count(15)<<"个15在multiset里\n";

 //find函数返回一个迭代器或常量迭代器,指向最先找到值的位置,
 //如果没有找到这个值,则返回一个等于调用end函数所返回值的迭代器或常量迭代器
 Ims::const_iterator result;
 result=intMultiset.find(15);
 if (result!=intMultiset.end())
 {
  cout<<"发现值15\n";
 }
 result=intMultiset.find(20);
 if (result==intMultiset.end())
 {
  cout<<"没有发现值20\n";
 }

 //使用insert函数将数组a的元素插入到Multiset中
 intMultiset.insert(a,a+SIZE);
 cout<<"出入后,multiset包含:\n";
 copy(intMultiset.begin(),intMultiset.end(),output);//copy算法将multiset中的元素赋值到标准输出

 //使用lower_bound和upper_bound函数,搜索值22在Multiset中最早出现的位置以及最后一次出现位置之后的那个位置
 //这两个函数都返回指向适当位置的iterator,或const_iterator。如果没有找到值,则返回等于end函数所返回的迭代器
 cout<<"\n22最早出现的位置的值是:"
  <<*(intMultiset.lower_bound(22));
 cout<<"\n22最后出现的位置的下一个位置的值是:"
  <<*(intMultiset.upper_bound(22));

 //实例化pair类的一个实例p。pair类的对象用于将一对值关联。
 pair<Ims::const_iterator,Ims::const_iterator> p;
 p=intMultiset.equal_range(22);
 cout<<"\n\nequal_range of 22:"<<"\n Lower bound:"
  <<*(p.first)<<"\n Upper bound:"<<*(p.second);
 cout<<endl;
 system("pause");
 return 0;
}


 

运行结果:

2.set关联容器

Set关联容器用于快速保存与提取不同的键。Set的实现与multiset相同,区别在于set键必须是唯一的。因此,如果试图在set中插入重复的键,则会忽略它。

Set支持双向迭代器,(而不是随机访问迭代器)。

下面的demo2演示了一个包含double值的set。

#include <iostream>
#include <set>
#include <algorithm>
#include <iterator>
using namespace std;

//使用了一个typedef,为函数对象less<double>按升序保存double值的set对象创建一个新的类型名
typedef set<double,less<double>> DoubleSet;

int _tmain(int argc, _TCHAR* argv[])
{
 const int SIZE = 5;
 double a[SIZE] ={2.1,4.2,9.5,2.1,3.7};
 //使用新的类型名DoubleSet实例化了一个doubleSet对象。构造函数调用取得数组a中位于a和a+SIZE之间的元素,并将它们插入到set中
 DoubleSet doubleSet(a,a+SIZE);
 ostream_iterator<double> output(cout," ");

 cout<<"doubleSet包含:";
 copy(doubleSet.begin(),doubleSet.end(),output);//使用copy算法输出set的内容
 //注意:2.1在数组中出现了2次,但在doubleSet中只出现一次

 //定义一个pair对象,它由一个DoubleSet的const_iterator和一个布尔值组成,这个对象保存了insert函数的结果
 pair<DoubleSet::const_iterator,bool> p;

 //使用insert函数将值13.8保存到set中。所返回的pair对象p,包含了指向set中值13.8的一个迭代器p.first和一个布尔值
 //如果值被插入,则布尔值为真;如果没有被插入(由于它已经在set中存在),则布尔值为假
 p = doubleSet.insert(13.8);
 cout<<"\n\n"<<*(p.first)
  <<(p.second ? " was":" was not")<<" inserted";
 cout<<"\ndoubleSet 包含:";
 copy(doubleSet.begin(),doubleSet.end(),output);

 p = doubleSet.insert(9.5);
 cout<<"\n\n"<<*(p.first)
  <<(p.second ? " was":" was not")<<" inserted";
 cout<<"\ndobuleSet 包含:";
 copy(doubleSet.begin(),doubleSet.end(),output);
 cout<<endl;

 system("pause");
 return 0;

}


 

运行结果:

3.multimap关联容器

multimap关联容器用于键以及关联值(键/值对)的快速保存与提取。

multimap和map中的元素都是键/值对而不是单个的值。插入到一个multimap或者map时,使用的是一个包含键和值的pair对象。

键的顺序由比较器函数对象确定。

multimap中允许重复的键,因此多个不同的值能够与同一键相关联。这通常成为一对多关系。

multimap支持双向迭代器(而不是随机访问迭代器)。

multimap的实现能够高效地搜索一个指定键相配对的所有值。

下面是demo3:

#include <iostream>
#include <map>
using namespace std;

//用typedef定义了别名Mmid,表示一个multimap类型,其键类型为int,与键相关联的值为double类型,并且元素是按升序排列的
typedef multimap<int,double,less<int>> Mmid;

int _tmain(int argc, _TCHAR* argv[])
{
 Mmid pairs;  //用新类型实例化一个multimap对象pairs

 //使用count函数确定键为15的键/值对的数量
 cout<<"There are currently "<<pairs.count(15)
  <<" pair whit key 15 in the multimap\n";

 //使用insert函数在这个multimap中添加新的键/值对
 pairs.insert(Mmid::value_type(15,2.7));  
 //表达式Mmid::value_type(15,2.7)创建了一个pair对象,其中first是int类型的键(15),second是double类型的值(2.7)
 pairs.insert(Mmid::value_type(15,99.3));

 cout<<"After inserts,there are "<<pairs.count(15)
  <<" pairs with key 15\n\n";

 //在multimap中再插入5个pair对象
 pairs.insert(Mmid::value_type(30,111.11));
 pairs.insert(Mmid::value_type(10,22.222));
 pairs.insert(Mmid::value_type(25,33.3333));
 pairs.insert(Mmid::value_type(20,9.345));
 pairs.insert(Mmid::value_type(5,77.54));

 cout<<"Multimap pairs contains:\nKey\tValue\n";

 for (Mmid::const_iterator iter = pairs.begin();
  iter != pairs.end();++iter)
 {
  cout<<iter->first <<'\t'<<iter->second<<'\n';
 }
 cout<<endl;
 system("pause");
 return 0;
}


 

运行结果:

4.map关联容器

map关联容器执行唯一的键与关联值的快速保存和提取。

Map中不允许重复的键,每个值都只能与一个键相关联。这种通常称为一对一映射。

Map也被称为关联数组。在map的下标运算符[]中提供键,能够在map中搜出与这个键相关联的值。

Map中任何位置都可以执行插入和删除操作。

下面demo4演示了map关联容器

#include <iostream>
#include <map>
using namespace std;

typedef map<int,double,less<int>> Mid;

int _tmain(int argc, _TCHAR* argv[])
{
 Mid pairs;

 pairs.insert(Mid::value_type(15,2.7));
 pairs.insert(Mid::value_type(30,111.11));
 pairs.insert(Mid::value_type(5,1010.1));
 pairs.insert(Mid::value_type(10,22.22));
 pairs.insert(Mid::value_type(25,33.333));
 pairs.insert(Mid::value_type(5,77.54));
 pairs.insert(Mid::value_type(20,9.345));
 pairs.insert(Mid::value_type(15,99.3));

 cout<<"pairs contains:\nKey\tValue\n";

 for (Mid::const_iterator iter = pairs.begin();
  iter != pairs.end(); ++iter)
 {
  cout<<iter->first<<'\t'<<iter->second<<'\n';
 }

 //使用map下标运算符。当下标值为map中已经存在的键时,这个运算符就返回相关联值的引用;
 //当下标值不是这个map中已经存在的键时,这个运算符就将这个键插入到map中,并返回一个引用,它能够用来将一个值与这个键相关联
 pairs[25] = 9999.99;   //用一个新值9999.99替换了与键25相关联的值
 pairs[40] = 8765.43;   //在这个map中插入一个新的键/值对

 cout<<"\nAfter subscript operations,pairs contains:\nKey\tValue\n";

 for (Mid::const_iterator iter2 = pairs.begin();
  iter2 != pairs.end(); iter2++)
 {
  cout<<iter2->first<<'\t'<<iter2->second<<'\n';
 }
 cout<<endl;
 system("pause");
 return 0;
}


 

运行结果:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值