boost中bimap双向映射的初级学习

boost的bimap相当于STL的map的升级版本, 具有双向映射. 学过STL的map的童鞋很容易掌握它的使用.

不过, 差别肯定是有的. 因为它是双向的, 所以有左右之分. 如:

boost::bimap<int,int> bm;

bm.left就相当于STL的map, bm.right就是把STL中的key-value键值对反过来, 变成value-key, 它相应的

first和second也就变成了value和key.

举例说明, 假我们要做一个电话簿, 有区号-城市的对应关系, 有时候我们有区号, 想得到城市, 或是有城市

想得到区号, 我们可能需要这样一个双向映射关系的电话簿, 我们可以这样:

1  typedef boost::bimap < std:: string ,std:: string >  bm_type;
2  typedef bm_type::value_type position;
3  bm_type bmPhone;
4  bmPhone.insert( position(  " 0771 " " 南宁 "  ) );
5 

这样, bmPhone里就插入了一个 "0771"-"南宁"的项.( 鄙人是广西人, 偏爱广西, 各位不要介意哈 ).

这里要注意的是, 在插入的时候, 使用的是 bm_type::value_type, 而不是STL的make_pair, 这一点是值

得注意的. 另一点就是, 如果插入 position( "0772", "南宁" )是会失败的, 会产生一个编译错误( 这可比

运行时失败要好得多辣 ), 因为bimap也是一个map, 不允许有重复键, 因为它是双向的, 右边的value也是

一个键值, 所以插入两个"南宁"是会失败的. 可能您会说, STL有multimap支持复制值的啊, bimap也是支持

的, 我们待会儿再说.

 

假设我们要通过一个区号去查找城市, 如有接口: std::string GetCityByCode( std::string strCode ); 那么我们

可以实现如下:

复制代码
1  std:: string  GetCityByCode( std:: string  strCode )
2  {
3      bm_type::left_const_iterator it;  //  也可以使用 const_iterator
4      it  =  bmPhone.left.find( strCode );  //  注意有个 .left
5       if  ( it  !=  bmPhone.left.end( ) )    //  注意是 .left.end( )
6           return  it -> second;
7       return   "" ;
8  }
复制代码

 

如果我们要通过城市查区号, 那就把left换成right就成了.

 

贴出完整源代码:

复制代码
//  bimap.cpp : 定义控制台应用程序的入口点。
//

#include 
" stdafx.h "

#include 
< iostream >
#include 
< boost / bimap.hpp >

class  PhoneManager {
public :
    PhoneManager( 
void  ) { Init( ); }
    
void  Init(  void  );
    
void  ListAll(  void  )  const ;
    std::
string  GetCityByAreacode( std:: string  strAreacode )  const ;
    std::
string  GetAreacodeByCity( std:: string  strCity )  const ;

private :
    typedef boost::bimap
< std:: string ,std:: string >  bm_type;
    typedef bm_type::left_const_iterator left_const_iterator;
    typedef bm_type::right_const_iterator right_const_iterator;
    bm_type _bmValues;
};


int  _tmain( int  argc, _TCHAR *  argv[])
{
    PhoneManager pm;
    pm.ListAll( );
    std::cout 
<<   " =========================Test=Result===============================\n " ;
    std::cout 
<<   " find 南宁 "   <<   " \n     result is: "   <<  pm.GetAreacodeByCity(  " 南宁 "  )  <<   ' \n ' ;
    std::cout 
<<   " find 梧州 "   <<   " \n     result is: "   <<  pm.GetAreacodeByCity(  " 梧州 "  )  <<   ' \n ' ;
    std::cout 
<<   " find 0771 "   <<   " \n     result is: "   <<  pm.GetCityByAreacode(  " 0771 "  )  <<   ' \n ' ;
    std::cout 
<<   " find 0774 "   <<   " \n     result is: "   <<  pm.GetCityByAreacode(  " 0774 "  )  <<   ' \n ' ;

    std::cin.
get ( );
    
return   0 ;
}

void  PhoneManager::Init(  void  )
{
    _bmValues.insert( bm_type::value_type( 
" 0771 " " 南宁 "  ) );
    _bmValues.insert( bm_type::value_type( 
" 0772 " " 柳州 "  ) );
    _bmValues.insert( bm_type::value_type( 
" 0773 " " 桂林 "  ) );
}

std::
string  PhoneManager::GetAreacodeByCity( std:: string  strCity )  const
{
    right_const_iterator it;
    it 
=  _bmValues.right.find( strCity );
    
if  ( it  !=  _bmValues.right.end( ) )
        
return  it -> second;
    
return   "" ;
}

std::
string  PhoneManager::GetCityByAreacode( std:: string  strAreacode )  const
{
    left_const_iterator it;
    it 
=  _bmValues.left.find( strAreacode );
    
if  ( it  !=  _bmValues.left.end( ) )
        
return  it -> second;
    
return   "" ;
}

void  PhoneManager::ListAll(  void  )  const
{
    left_const_iterator it;
    
for  ( it  =  _bmValues.left.begin( ); it  !=  _bmValues.left.end( );  ++ it ) {

        std::cout 
<<  it -> first  <<   '   '   <<  it -> second  <<   ' \n ' ;
    }
}
复制代码

 

 

有时候, 我们觉得 it->first, it->second看起来很别扭,  让人觉得迷惑, 不知道 first和 second是啥, 这个时候, 我们可以使用标签功能.

复制代码
 1  typedef boost::bimap <
 2      tagged <  std:: string , areacode > ,   //  在这里加标签
 3      tagged <  std:: string , city     >
 4  >  bm_type;
 5  typedef bm_type::value_type position;
 6  bm_type bmTest;
 7  bmTest.insert( position(  " 0771 " " 南宁 "  ) );
 8  for  ( bm_type::map_by < areacode > ::const_iterator  //  不用使用.left
 9      i   =  bmTest.by < areacode > ().begin();   //  这里也不必指定 .left
10      i  !=  bmTest.by < areacode > ().end( );
11       ++ i ) {
12      std::cout  <<  i -> get < areacode > ( )   //  这里可以很明确地指示使用areacode
13                 <<   " <--> "
14                 <<  i -> get < city > ( )       //  还是city, 而不用去使用混乱的first和second
15                 <<   ' \n ' ;
16  }
17 
复制代码

 

 

最后, 要说一下关于重复键. BOOST里没有 multibimap, 但是我们可以充分利用模板的特性. 例子好说明:

拿例子来说, 每个身份证都对应一个人的名字, 但人名是有重复的. 我们可以这样做:

复制代码
1  #include  < boost / bimap / multiset_of.hpp >
2 
3  typedef boost::bimap <
4    tagged <  std:: string ,   id > ,
5    multiset_of <  tagged <  std:: string , name >   >   //  这里使用multiset_of
6  >  bm_type;
复制代码

 

 

注意, 映射中默认都是排过序的, 如果不需要排序, 可以使用 unordered_set_of.

 

http://www.cnblogs.com/lin1270/archive/2011/01/12/1933908.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Boost库是一个功能强大的C++库集合,提供了许多常用的函数和模块。以下是一些常用的Boost库函数: 1. 字符串和文本处理库:Boost库提供了丰富的字符串处理功能,比如lexical_cast用于数值转换,format用于字符串格式化,string_algo用于字符串算法。 2. 类型推导:Boost库提供了BOOST_AUTO和BOOST_TYPEOF用于类型推导,可以方便地获取表达式的类型。 3. 智能指针:Boost库提供了多种智能指针,如scoped_ptr、shared_ptr、weak_ptr等,用于管理动态分配的内存。 4. 数组和容器:Boost库提供了多维数组multi_array、动态多维数组、普通数组array、散列容器unordered_set、unordered_map、双向映射容器bimap、环形缓冲区circular_buffer等,方便了数组和容器的操作和管理。 5. XML和JSON解析:Boost库提供了property_tree模块,可用于解析和处理XML和JSON数据。 6. 简化循环:Boost库提供了BOOST_FOREACH宏,可用于简化循环操作。 7. 随机数库:Boost库提供了Random模块,用于生成随机数。 8. 引用库:Boost库提供了ref模块,用于处理引用。 9. 绑定库:Boost库提供了bind模块,用于函数对象的绑定。 10. 线程库:Boost库提供了thread模块,用于跨平台多线程编程。 这些只是Boost库的一部分常用函数,Boost库还有许多其他功能和模块可供使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ Boost库:工厂函数 make_shared](https://blog.csdn.net/u014779536/article/details/116400788)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【BOOST C++库】BOOST C++库20个分类指南](https://blog.csdn.net/gongdiwudu/article/details/127961836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值