我正在一个项目中,我有两个独特的元素集。一个集合中的任何元素都可以与另一集合中的任何元素相关。
例子:
集合1:{A,B,C}
集2:{1、2、3、4}
允许的关系:
(A,1)(A,3)
(B,1)(B,4)
(C,1)(C,3)(C,4)
单个关系表示为一对括号内的两个set元素。
在我的特定项目中,这两个集合的元素都是对象,并且我希望对存储的所有对象的所有引用都解析为一个对象(例如,所有包含A的关系都将引用同一个对象A,对于关系另一侧对其他集合的引用)。
我当时正在考虑使用Boostbimap
解决这个问题。我正在研究用于bimap的左右两半以及这两个集合之间的关系的潜在集合类型,并一直在尝试确定哪些集合是正确的。
对于的左右两半bimap
,我一直认为set_of
CollectionType
正确,因为我的两组对象是一组,而且我不希望我的任何元素重复bimap
。
但是,当我在实践中尝试此操作时,最终我无法在插入关系(A,1)之后插入关系(B,1),因为插入必须在左边的两个地方都有效并对其进行正确的看法。为了更正此问题,我将CollectionType
两个半部的均更改为multiset_of
。所有值均已正确插入,但这是否意味着我bimap
现在具有原始集合元素的重复副本?
为了对此进行纠正,我开始研究更改的两半之间关系的集合类型bimap
。由于关系类型的集合类型默认为的左半部分,因此bimap
我认为这multiset_of
是不正确的,并将其指定为set_of
。但是,我不确定这是否可以解决我原来的问题,即从原始集中获得多个对象副本。
我真正需要做的就是查看集合2中与集合1中的元素相关的所有对象。Boostbimap
对我来说是正确的路线吗?我选择了正确的集合和关系类型吗?顺便说一句,我试图自定义地图,以使其具有快速的搜索时间,而不必担心插入时间(删除和修改将永远不会发生,地图会被初始化,然后用于之后的查找)。我应该只编写自定义数据结构吗?
我完全同意杰里的回答。如果要对图形进行建模,请考虑使用例如邻接表,边列表或矩阵表示。
Paul的回答有点麻烦,下面是使用Boost Multi Index的示例:
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/ordered_index.hpp>
struct T1 {
std::string name;
bool operator<(T1 const& o) const { return name < o.name; }
};
struct T2 {
int id;
bool operator<(T2 const& o) const { return id < o.id; }
};
namespace bmi = boost::multi_index;
struct Relation {
T1 const* key1;
T2 const* key2;
std::string const& name() const { return key1->name; }
int id () const { return key2->id; }
friend std::ostream& operator<<(std::ostream& os, Relation const& r) {
return os << "(" << r.name() << ", " << r.id() << ")";
}
};
using RelationTable = bmi::multi_index_container<Relation,
bmi::indexed_by<
bmi::ordered_unique<bmi::tag<struct by_composite>,
bmi::composite_key<Relation,
bmi::const_mem_fun<Relation, std::string const&, &Relation::name>,
bmi::const_mem_fun<Relation, int, &Relation::id>
>
>
> >;
#include <set>
int main() {
using namespace std;
set<T1> set1 { {"A"}, {"B"}, {"C"} };
set<T2> set2 { {1}, {2}, {3}, {4} };
// convenient data entry helpers
auto lookup1 = [&set1](auto key) { return &*set1.find(T1{key}); }; // TODO error check?
auto lookup2 = [&set2](auto key) { return &*set2.find(T2{key}); };
auto relate = [=](auto name, auto id) { return Relation { lookup1(name), lookup2(id) }; };
// end helpers
RelationTable relations {
relate("A", 1), relate("A", 3),
relate("B", 1), relate("B", 4),
relate("C", 1), relate("C", 3), relate("C", 4),
};
for (auto& rel : relations)
std::cout << rel << " ";
}
印刷
(A, 1) (A, 3) (B, 1) (B, 4) (C, 1) (C, 3) (C, 4)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句