c++的map总结

首先贴源码:
#include <iostream>
#include <map>
#include "bimap.hpp"
#include "bimap/multiset_of.hpp"


using namespace std;
using namespace boost;
using namespace boost::bimaps;

template <class T>
void bsmap_traverse(T &map) {
    class T::iterator iter;
    for (iter = map.begin(); iter != map.end(); ++iter)
        cout<<"key: "<<iter->first<<", val: "<<iter->second<<endl;
}


int main() {
    map<int, string> smap;
    multimap<int, string> mmap;
    
    mmap.insert(make_pair(1, "ak47"));
    mmap.insert(make_pair(2, "m4a1"));
    mmap.insert(make_pair(2, "sig552"));
    mmap.insert(make_pair(3, "eagle"));
    mmap.insert(make_pair(4, "usp"));
    mmap.insert(make_pair(5, "o4"));

    typedef map<int, string>::iterator siter_t;
    typedef multimap<int, string>::iterator miter_t;
    miter_t miter;

    for (miter = mmap.begin(); miter != mmap.end(); ++miter) {
        cout<<"key: "<<miter->first<<", val: "<<miter->second<<endl;
    }
    cout<<"traverse multimap"<<endl;
    int i;
    for (i = 0, miter = mmap.begin(); miter != mmap.end(); ++miter, ++i) {
        int key_num = mmap.count(miter->first);
        if (key_num > 1) {
            cout<<"mkey: "<<miter->first<<", val"<<i<<": "<<miter->second<<endl;
        }
    }
    cout<<"only find value of multikey by count func"<<endl;

    typedef pair<miter_t, miter_t> miter_r;
    miter_r range2 = mmap.equal_range(2);
    miter_r range13 = make_pair(mmap.find(1), mmap.find(3));

    for (miter = range2.first; miter != range2.second; ++miter) {
        cout<<"key: "<<miter->first<<", val: "<<miter->second<<endl;
    }

    cout<<"equal_range"<<endl;

    for (miter = range13.first; miter != range13.second; ++miter) {
        cout<<"key: "<<miter->first<<", val: "<<miter->second<<endl;
    }

    cout<<"iterator step by range of iterator"<<endl;

    miter = mmap.find(2);
    mmap.erase(miter);
    for (miter = mmap.begin(); miter != mmap.end(); ++miter)
        cout<<"key: "<<miter->first<<", val: "<<miter->second<<endl;

    cout<<"only find and del one val of multi-key"<<endl;
    
    boost::bimap<int, string> bsmap;
    typedef boost::bimap<int, string>::value_type position;
    bsmap.insert(position(1, "ak47"));
    bsmap.insert(position(2, "m4a1"));
    bsmap.insert(position(3, "usp"));
    bsmap.insert(position(4, "eagle"));
    bsmap.insert(position(5, "sig552"));

    bsmap_traverse(bsmap.left);
    bsmap_traverse(bsmap.right);
    cout<<"traverse bimap"<<endl;

    boost::bimap<int, string>::left_iterator iter_l;
    boost::bimap<int, string>::right_iterator iter_r;

    iter_l = bsmap.left.find(1);
    bsmap.left.erase(iter_l);
    bsmap_traverse(bsmap.left);
    bsmap_traverse(bsmap.right);
    cout<<"traverse after del a elem by left key"<<endl;

    iter_r = bsmap.right.find("eagle");
    bsmap.right.erase(iter_r);
    bsmap_traverse(bsmap.left);
    bsmap_traverse(bsmap.right);
    cout<<"traverse after del a elem by right key"<<endl;

    cout<<"bimap(single key, not multikey) traverse by key and value"<<endl;

    typedef boost::bimap< multiset_of<string>,  
                         multiset_of<string>
    > bmmap_t;
    bmmap_t bmmap1;

    bmmap1.insert(bmmap_t::value_type("ld", "ak47"));
    bmmap1.insert(bmmap_t::value_type("sz", "awp"));
    bmmap1.insert(bmmap_t::value_type("wy", "awp"));
    bmmap1.insert(bmmap_t::value_type("gd", "m4a1"));
    bmmap1.insert(bmmap_t::value_type("bf", "ak47"));
    bmmap1.insert(bmmap_t::value_type("ld", "awp"));
    bmmap1.insert(bmmap_t::value_type("sz", "ak47"));
    bmmap1.insert(bmmap_t::value_type("gd", "awp"));
    bmmap1.insert(bmmap_t::value_type("wy", "ak47"));

    
    pair<bmmap_t::left_iterator, bmmap_t::left_iterator> range_ld = bmmap1.left.equal_range("ld");
    for (bmmap_t::left_iterator iter = range_ld.first; iter != range_ld.second; ++iter)
        cout<<"name: "<<iter->first<<", gun: "<<iter->second<<endl;
    cout<<"which gun ld used"<<endl;

    pair<bmmap_t::right_iterator, bmmap_t::right_iterator> range_ak47 = bmmap1.right.equal_range("ak47");
    for (bmmap_t::right_iterator iter_ak47 = range_ak47.first; iter_ak47 != range_ak47.second; ++iter_ak47)
        cout<<"ak47 user: "<<iter_ak47->second<<endl;
    cout<<"who use ak47"<<endl;


    return 0;

}


一、单向且键-单值的map(std::map):略

二、单向且键-多值的map(std::multimap):

在multimap的内部存储结构中,单key多值事实上也是“连续”存储的,比如例子中的代码如下:

    mmap.insert(make_pair(1, "ak47"));
    mmap.insert(make_pair(2, "m4a1"));
    mmap.insert(make_pair(3, "eagle"));
    mmap.insert(make_pair(2, "sig552"));
    mmap.insert(make_pair(4, "usp"));
    mmap.insert(make_pair(5, "o4"));

mmap的遍历结果是:
key: 1, val: ak47
key: 2, val: m4a1
key: 2, val: sig552
key: 3, val: eagle
key: 4, val: usp
key: 5, val: o4

当需要找到哪个key对应了多个值,可以用multimap的count方法,mmap.count(key)的返回值大于1,即说明该key对应多个value。

又因为在multimap的存储结构是“连续”的,所以当使用find方法获取到该key的迭代器时,将可以连续获取到该key的value。

对于多value的获取,用equal_range方法比较合适,如例子中值为2的key对应了多个value,那么可以用equal_range方法获取到该key的迭代器区间:
pair<miter_t, miter_t> range2 = mmap.equal_range(2);

range2作为一个pair,其first是该key在multimap中第一次出现的迭代器,其second是该key在multimap中最后一次出现的迭代器


multimap的find方法和erase方法与map相同,略。


--------------------------------------------------------------------------------  一、二包含标准库的头文件<map>

三、双向且键-单值的map(boost::bimap):

包含boost的boost/bimap.hpp

using namespace boost;
using namespace boost::bimaps;       ///boost::bimap的multimet_of在此namespace定义


结构类型:boost::bimap<XXX, YYY>

注意boost::bimap的值类型,不是标准库的pair(xxx,yyy),而是boost::bimap<XXX, YYY>::value_type(xxx,yyy),如例子的插入操作:

    boost::bimap<int, string> bsmap;
    typedef boost::bimap<int, string>::value_type position;

    bsmap.insert(position(1, "ak47"));
    bsmap.insert(position(2, "m4a1"));
    bsmap.insert(position(3, "usp"));
    bsmap.insert(position(4, "eagle"));
    bsmap.insert(position(5, "sig552"));

bimap可以根据key为key查找value,还可以根据value为key查找key,即双向map,

当以key为key查找value时,迭代器是boost::bimap<XXX, YYY>::left_iterator,当以value为key查找key时,迭代器是boost::bimap<XXX, YYY>::right_iterator,

如例子中的bsmap_traverse函数的执行过程。注意,boost的bimap并不支持单key对应多个value。

支持双向查找的boost的bimap是有十分重大的意义的,避免了倒查时的线性遍历或者被迫创建正反两个map。


如果双向map需要实现键-多值,boost::bimap本身不支持,但可以通过multiset_of实现,如例子的:

typedef boost::bimap< multiset_of<string>,  
                                         multiset_of<string>
> bmmap_t;

即可实现双向key-多值的map结构bmmap_t,随后的插入操作,即可插入键-多值:

    bmmap_t bmmap1;

    bmmap1.insert(bmmap_t::value_type("ld", "ak47"));
    bmmap1.insert(bmmap_t::value_type("sz", "awp"));
    bmmap1.insert(bmmap_t::value_type("wy", "awp"));
    bmmap1.insert(bmmap_t::value_type("gd", "m4a1"));
    bmmap1.insert(bmmap_t::value_type("bf", "ak47"));
    bmmap1.insert(bmmap_t::value_type("ld", "awp"));
    bmmap1.insert(bmmap_t::value_type("sz", "ak47"));
    bmmap1.insert(bmmap_t::value_type("gd", "awp"));
    bmmap1.insert(bmmap_t::value_type("wy", "ak47"));

可以生动的了解下这个双向且键-多值的map的含义哈,左值是我和我的一众同事的人名的简写,右值是他们惯用的CS的枪械,如ld(就是我)惯用枪械包括ak47和awp,

可以继续通过equal_range方法查找到左值为ld的迭代器集合,即可查到ld为左值的全部元素,看看这个人的惯用枪械是哪些;

    pair<bmmap_t::left_iterator, bmmap_t::left_iterator> range_ld = bmmap1.left.equal_range("ld");
    for (bmmap_t::left_iterator iter = range_ld.first; iter != range_ld.second; ++iter)
        cout<<"name: "<<iter->first<<", gun: "<<iter->second<<endl;
    cout<<"which guns ld used"<<endl;

反过来,同样通过equal_range方法查找到右值为ak47的全部元素,即查找到惯用枪械包括ak47的全部的人~:

    pair<bmmap_t::right_iterator, bmmap_t::right_iterator> range_ak47 = bmmap1.right.equal_range("ak47");
    for (bmmap_t::right_iterator iter_ak47 = range_ak47.first; iter_ak47 != range_ak47.second; ++iter_ak47)
        cout<<"ak47 user: "<<iter_ak47->second<<endl;

    cout<<"who use ak47"<<endl;


最后注意下,bimap在一些较早的boost版本中是没有的,如1.32版本就是没有的,当前使用的1.54版本中已有。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值