pair、map、set、multiset、multimap用法简介

一、pair简介

在介绍这几种容器之前,我们先来看下pair,pair是一种模板类型,其中包含了两个数据值,两个数据的类型可以不同,定义如下:

pair<int, string> a;

表示a中有两个数据类型,一个是int类型,一个是string类型的,如果在创建pair时候没有对其初始化,则调用默认的构造函数对其初始化。

也可以按照以下的方式在定义的时候进行初始化

pair<int, string> a(3, "boy");

生成一个pair对象

我们可以使用make_pair对已存在的两个数据构造一个新的pair类型,如下所示:

int Int_Data = 3;
string String_Data = "boy";
pair<int, string> Pair;
Pair = make_pair(Int_Data, String_Data);

那么make_pair是如何创建的呢。

下面我们来看下C++98中make_pair是如何创建的

template <class T1,class T2>
pair<T1,T2> make_pair (T1 x, T2 y)
{
   return ( pair<T1,T2>(x,y) );
}

由此可见make_pair内部调用了拷贝构造函数,直接返回一个pair对象。

pair结构

这里写图片描述
由此可见pair的两个成员分别是first与second。

当我们需要访问pair里面的成员时,便用点操作符来访问它的成员。

二、set(集合)

(1)set特性

  1. set的元素的键值就是实值,实值就是键值,仅有一个值。
  2. 不允许有两个元素拥有相同的键值。
  3. 所有的元素键值都会被自动排序(默认情况下是升序)
  4. set的iterators是一种constant itertors(相对于mutable iterators)。
  5. 是使用红黑树作为底层的数据结构
template < class T,                    // set::key_type/value_type    
           class Compare = less<T>,    // set::key_compare/value_compare  
           class Alloc = allocator<T>  // set::allocator_type  
           > class set;

set也是一个模板,它的第一个模板参数是键值类型。第二个参数是一个仿函数,它传入了键值的比较方式(默认升序),第三个参数是空间配置器。

(2)set成员类型

在C++98与C++11中set的成员类型并没有改变多少,下面我们来看下在C++98下的成员类型:

这里写图片描述

(3)set常用接口

接下来我们看下Set的常用接口。

这里写图片描述

(4)set的使用

测试程序代码如下:

#include <iostream>
#include <set>
using namespace std;
int main()
{
    int arr[] = { 0,5,6,7,1,2,3,4 };//默认排序
    set<int> _Set(arr, arr + sizeof(arr) / sizeof(arr[0]));

    cout << "Size=" << _Set.size() << endl;
    cout << "5 Count=" << _Set.count(5) << endl;

    _Set.insert(5);
    cout << "Size=" << _Set.size() << endl;
    cout << "5 Count=" << _Set.count(5) << endl;

    _Set.insert(9);
    cout << "Size=" << _Set.size() << endl;
    cout << "9 Count=" << _Set.count(9) << endl;

    _Set.erase(3);
    cout << "Size=" << _Set.size() << endl;
    cout << "3 Count=" << _Set.count(3) << endl;

    _Set.erase(10);
    cout << "Size=" << _Set.size() << endl;
    cout << "10 Count=" << _Set.count(10) << endl;

    set<int>::iterator iter1 = _Set.begin();
    set<int>::iterator iter2 = _Set.end();

    for (; iter1 != iter2; iter1++)
        cout << *iter1 << " ";
    cout << endl;

    //此处使用STL的算法find并不是一个好的方法
    iter1 = find(_Set.begin(), _Set.end(), 7);
    if (iter1 != _Set.end())
        cout << *iter1 << endl;
    else
        cout << "not find!" << endl;

    iter1 = find(_Set.begin(), _Set.end(), 12);
    if (iter1 != _Set.end())
        cout << *iter1 << endl;
    else
        cout << "not find!" << endl;

    //根据容器所提供的find函数来搜索元素
    //会比STL中算法find更有效。因为stl中find只是循序搜索
    iter1 = _Set.find(0);
    if (iter1 != _Set.end())
        cout << *iter1 << endl;
    else
        cout << "not find!" << endl;

    iter1 = _Set.find(15);
    if (iter1 != _Set.end())
        cout << *iter1 << endl;
    else
        cout << "not find!" << endl;
    system("pause");
    return 0;
}

运行结果如下:

这里写图片描述

三、map(映射)

(1)map特性

  1. 所有的元素都会根据元素的键值自动被排序(默认升序)。
  2. map的所有元素都是pair,同时拥有键值key与实值value。
  3. map不允许两个元素拥有相同的键值。
  4. map的键值是不能被修改的,但是实值可以被修改。
  5. map底层使用的数据结构是红黑树。
  6. map重载了[],查询速度快。
template < class Key,                                     // map::key_type
           class T,                                       // map::mapped_type
           class Compare = less<Key>,                     // map::key_compare
           class Alloc = allocator<pair<const Key,T> >    // map::allocator_type
           > class map;

map也是一个模板,它有四个模板参数类型,第一个是键值的类型,第二个是实值类型,第三个是仿函数,传入的是键值比较方式,默认升序,第四个参数是空间配置器。

(2)map成员类型

这里写图片描述

(3)map常用接口

这里写图片描述

注意:

map在次多了一个operator[]

mapped_type& operator[](const key_type& k)

map中的operator[ ]是最常用的,然而在set中并没有对它进行重载。作用是:如果map中有k,则它就把这个k所对应的value的引用返回,如果map中没有这个k,这时它会调用insert(pair<K,V>(k,V())),将k和V的缺省值对应插入进去,并返回这个value的引用。

(4)map的使用

测试程序代码如下:

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
    //由于string是键值,int是实值
    //所以出来的顺序不一定是1234
    map<string, int> _Map;
    _Map[string("张三")] = 1;
    _Map[string("李四")] = 2;
    _Map[string("王五")] = 3;
    pair<string, int> _Pair(string("小六"), 4);
    _Map.insert(_Pair);
    map<string, int>::iterator iter = _Map.begin();
    for (; iter != _Map.end(); ++iter)
    {
        cout << iter->first << " " << iter->second << " ";
    }
    cout << endl;

    map<string, int>::iterator iter2;
    iter2 = _Map.find(string("小六"));
    if (iter != _Map.end())
        cout << "find" << endl;
    else
        cout << "not find" << endl;
    iter2->second = 5;
    cout << iter2->first << " " << iter2->second << endl;
    cout << _Map.empty() << endl;
    _Map.clear();
    cout << _Map.empty() << endl;
    return 0;
}

运行结果如图:
这里写图片描述

四、multiset

multiset的特性和用法与set完全相同,唯一的差别在于它允许键值重复,它的插入操作采用的底层机制是红黑树的insert_equal()而不是insert_unique()。
1. multiset的删除是删除所有值为key的结点。
2. multiset允许键值重复,调用的是insert_equal()。

五、multimap

multimap的特性和用法与map完全相同,唯一的差别在于它允许键值重复,它的插入操作采用的底层机制是红黑树的insert_equal()而不是insert_unique()。
multimap中并没有向map一样的有operator[ ],因为编译器也并不知道这样会返回多少个结果。
1. multimap的键值key和元素value是多对多的关系。
2. 允许键值重复。
3. 删除key既是删除所有值为key的元素。
4. 没有向map一样的有operator[ ]。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值