指引网

当前位置: 主页 > 编程开发 > C >

C++中 set,multiset,map,multimap 关联容器实例教程

来源:网络 作者:佚名 点击: 时间:2017-07-19 23:08
[摘要]  本教程我们通过实例,来讲讲C++中关联容器 set,multiset,map,multimap 的基础及异同。

测试环境:windows 7 vs2010

内部元素有序排列,新元素插入的位置取决于它的值,查找速度快。

除了各容器都有的函数外,还支持以下成员函数:

find: 查找等于某个值的元素(x小于y和y小于x同时不成立即为相等)
lower_bound: 查找某个下界
upper_bound: 查找某个上界
equal_range: 同时查找上界和下界
count:计算等于某个值的元素个数(x小于y和y小于x同时不成立即为相等)
insert: 用以插入一个元素或一个区间

在学习关联容器之前,我们先要学习pair模板,pair模板是struct形式,因此其内部成员默认都是公有的。

template<class _T1, class _T2> //两个类型参数  
struct pair  
{  
    typedef _T1 first_type;//_T1定义成first_type,_T2定义成second_type  
    typedef _T2 second_type;  
    _T1 first; //first 是_T1 类型  
    _T2 second; //seconde 是_T2类型  
    pair(): first(), second() { } //无参构造函数  
    pair(const _T1& __a, const _T2& __b)  
    : first(__a), second(__b) { }// 分别用__a初始化first,__b去初始化second  
    template<class _U1, class _U2> //这是一个模板函数构造函数,其通过一个pair对象去初始pair对象的first和second对象   
    pair(const pair<_U1, _U2>& __p)  
    : first(__p.first), second(__p.second) { }  
};


值得强调的是map/multimap容器中存放的都是pair对象,且按照first成员变量从小到大排序的。

第三个构造函数实例

pair<int,int>
p(pair<double,double>(5.5,4.6));
// p.first = 5, p.second = 4


下面看下set和multiset(set和multiset区别在set不允许有重复的key值)

template<class Key, class Pred= less<Key>,  
class A = allocator<Key> >  
class multiset{ …… };


Pred类型的变量决定了multiset中的元素,“一个比另一个小”是怎么定义的。multiset运行过程中,比较两个元素x,y的大小的做法,就是生成一个Pred类型的变量,假定为op,若表达式op(x,y) 返回值为true,则x比y小。
Pred的缺省类型是less<Key>。

template<class T>  
structless : public binary_function<T, T, bool>  
{   
    bool operator()(const T& x, const T& y) const  
    {   
        return x <y;   
    }  
};


//less模板是靠< 来比较大小的 ,因此当key为类时候,则该类必须重载运算符

01.png

#include<iostream>  
#include<set>  
using namespace std;  
void main()  
{  
    set<int>::iterator setIter;  
    pair<set<int>::iterator,set<int>::iterator> mypair;  
    pair<set<int>::iterator,bool> result;  
    set<int> myset;  
    for(int i=0;i<10;i++)  
    {  
        myset.insert(i);  
    }  
    result=myset.insert(3);//set insert返回pair对象 而multiset返回迭代器  
    if(!result.second)  
    {  
        cout<<"3 已经存在"<<endl;  
    }  
    setIter=myset.find(2);//find函数返回迭代器  
    if(setIter!=myset.end())  
    {  
      cout<<*setIter<<endl;  
    }  
    else  
    {  
        cout<<"not find"<<endl;  
    }  
  
  
    mypair=myset.equal_range(4);//同时求得lower_bound和upper_bound  
    cout<<"lower_bound:"<<*mypair.first<<endl;  
    cout<<"upper_bound:"<<*mypair.second<<endl;  
  
    for(setIter=myset.begin();setIter!=myset.end();)  
    {  
        if(*setIter%2==0) //删除偶数  
        {  
          setIter=myset.erase(setIter);  
        }  
        else  
        {  
            setIter++;  
        }  
    }  
    cout<<"删除偶数后"<<endl;  
    for(setIter=myset.begin();setIter!=myset.end();setIter++)  
    {  
        cout<<*setIter<<endl;  
    }  
    cin.get();  
}


01.png


map/multimap里放着的都是pair模版类的对象,且按first从小到大排序,其中map中key不允许重复。

multimap  
template<classKey, class T, class Pred= less<Key>,  
class A = allocator<T> >  
class multimap{  
….  
typedefpair<const Key, T> value_type;  
…….  
}; //Key 代表关键字的类型



multimap中的元素由<关键字,值>组成,每个元素是一个pair对象,关键字就是first成员变量,其类型是Key
multimap中允许多个元素的关键字相同。元素按照first成员变量从小到大排列,缺省情况下用less<Key>定义关键字的“小于”关系。

#include<iostream>  
#include<map>  
using namespace std;  
void main()  
{  
    map<int,string> stu_name;// 编号 姓名 其中是按照编号排序 其是键值对  
    map<int,string>::iterator mapIter;  
    stu_name.insert(map<int,string>::value_type(1,"zhang san"));  
    stu_name.insert(map<int,string>::value_type(2,"li si"));  
    stu_name.insert(make_pair(3,"wang er")); //使用make_pair也行  
  
  
    mapIter=stu_name.find(2);//  
    if(mapIter!=stu_name.end())  
    {  
        cout<<mapIter->second.c_str()<<endl;  
    }  
    else  
    {  
        cout<<"not find"<<endl;  
    }  
  
    for(mapIter=stu_name.begin();mapIter!=stu_name.end();mapIter++)  
    {  
        cout<<mapIter->first<<":"<<mapIter->second.c_str()<<endl;  
    }  
  
    cin.get();  
}






关联容器:set multiset map multimap比较

一、
  1)set 只能是单一的值,它是存储不重复的元素,不能有两个相同的元素,可以         用pair<set<int>::iterator,bool> ret;键值对来判断是否两个元素是否一样;
用if (ret.second==false) it=ret.first;可以判断是否失败;用*(ret.fisrt)可以得到相同的值。
  2)set的元素值是它的键值本身。而map是有key 和 value
  3)set都会对元素进行有序的排序。
 
二、
  1)multiset 可以储存相同的元素.
  2)insert返回的是迭代器。
  3)其他同set
 
三、
  1)map储存元素是有格式的key和value值。map是一种特殊的set,它的所有元素都是pair<key,value>map最大的特性在于map提供了下标subscript操作的能力,你可以向数组一样操作map[key]来引用相应的值。
  2)可以根据key找到关键字。几乎所有针对map的操作都是基于key的。比如,排序就是通过比较key来进行的。
  3)用树形结构储存,所以查找时间短。
  4)key是唯一不同步。每一个元素都有一个键值对。
  5)也是有序的。
 
四、
  multimap特点; map不能有重复的键值对,即如果插入键相同的键值对,则将覆盖掉同键值的键值对。
multimap则不会覆盖。

------分隔线----------------------------