#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版本中已有。