Boost::Bimap的双向多映射等价于什么?

20

问题的第一部分是我想使用boost::bimap,但从文档中不清楚如何定义双向多映射。

问题的第二部分是我需要它在一个方向上是map,在另一个方向上是multimap,这可以使用boost::bimap完成吗?

有没有人对此有经验或者能够指向正确的页面?

2个回答

18

所有的内容都在文档中... http://www.boost.org/doc/libs/1_51_0/libs/bimap/doc/html/boost_bimap/the_tutorial/discovering_the_bimap_framework.html

typedef boost::bimap<bimaps::multiset_of<int>, bimaps::set_of<int>> bimap_t;

例子。

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

namespace bimaps = boost::bimaps;

int main()
{
   typedef boost::bimap<bimaps::multiset_of<int>, bimaps::set_of<int>> bimap_t;
   typedef bimap_t::value_type value_type;
   bimap_t bimap;
   bimap.insert(value_type(1, 1));
   bimap.insert(value_type(1, 2));
   auto& left = bimap.left;
   auto it = left.find(1);
   std::cout << "LEFT" << std::endl;
   for (; it != left.end(); ++it)
   {
      std::cout << it->first <<  " " << it->second << std::endl;
   }
   auto& right = bimap.right;
   auto r_it = right.find(2);
   std::cout << "RIGHT" << std::endl;
   for (; r_it != right.end(); ++r_it)
   {
      std::cout << r_it->first << " " << r_it->second << std::endl;
   }
}

12

对于你的问题的第一部分(如何定义双向多映射?),ForEverR的答案部分正确。

对于第二部分(访问一个在一个方向上是map,在另一个方向上是multimap的bimap)他是不正确的。

正确的访问方式是:[http://rextester.com/BXBDHN12336]:

//bimap operations

#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>

int main()
{
   typedef boost::bimap<boost::bimaps::multiset_of<int>, boost::bimaps::set_of<int>> bimap_t;
   typedef bimap_t::value_type value_type;
   bimap_t bimap;
   bimap.insert(value_type(1, 1));
   bimap.insert(value_type(10, 50)); 
   bimap.insert(value_type(1, 2));
   bimap.insert(value_type(9, 15));   

   typedef bimap_t::left_const_iterator l_itr_t;
   typedef std::pair<l_itr_t,l_itr_t> l_itr_range_t;

   l_itr_range_t ii = bimap.left.equal_range(1);

   std::cout << "LEFT" << std::endl;        
   for(l_itr_t it = ii.first; it != ii.second; ++it)
   {
     std::cout << "Key = " << it->first << "    Value = " << it->second << std::endl;
   }  

   std::cout << "RIGHT" << std::endl;
   std::cout << "Key = " << 1 << "    Value = " << bimap.right.at(1) << std::endl;
}

stdout:
LEFT
Key = 1    Value = 1
Key = 1    Value = 2
RIGHT
Key = 1    Value = 1

ForEverR的示例“似乎”可以运行,因为插入数据的顺序,但是请注意,当您在末尾插入另外一对数据bimap.insert(value_type(9,15));时的结果:

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

namespace bimaps = boost::bimaps;

int main()
{
   typedef boost::bimap<bimaps::multiset_of<int>, bimaps::set_of<int>> bimap_t;
   typedef bimap_t::value_type value_type;
   bimap_t bimap;
   bimap.insert(value_type(1, 1));
   bimap.insert(value_type(1, 2));
   bimap.insert(value_type(9, 15));
   auto& left = bimap.left;
   auto it = left.find(1);
   std::cout << "LEFT" << std::endl;
   for (; it != left.end(); ++it)
   {
      std::cout << it->first <<  " " << it->second << std::endl;
   }
   auto& right = bimap.right;
   auto r_it = right.find(2);
   std::cout << "RIGHT" << std::endl;
   for (; r_it != right.end(); ++r_it)
   {
      std::cout << r_it->first << " " << r_it->second << std::endl;
   }
}

stdout: 
LEFT
1 1
1 2
9 15
RIGHT
2 1
15 9

1
我不确定你所说的“似乎有效”的意思。你得到的输出是因为它和r_it是用find()在multimap的中间某个位置初始化的。如果使用begin()进行初始化,则所有三个pair都会正确打印。 - namezero
1
是的,但这里的重点不是打印三个对。而是访问bimap(从左侧和/或右侧)并检索给定键的对。我已经编辑了我的回答,包括一个例子,您可以使用equal_range来实现这一点。希望这可以帮助到您。 - Javier Bravo
@JavierBravo,感谢您更新了这个答案。但是,实际上您完全错过了重点:**在Coliru上实时运行**。 - sehe
2
这是equal_range示例的简化版本:**Live On Coliru** /cc @namezero 我认为我们可以考虑你糟糕的迭代器处理,并且甚至一年多都没有看到错误足以理解为什么在调用站点之外保持复杂性很重要 :) - sehe
@sehe 哇,我完全不记得这个帖子了...未经测试:但是 boost::bimap<bimaps::multiset_of<int>, bimaps::multiset_of<int>> 不应该可以工作吗?*编辑:再次阅读原始问题;“简单”地图在一个方向上是必需的。 - namezero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接