假设我已经定义了一个类型,如
struct Item
{
Item(int i, float j) : x(i), y(j) {}
int x;
float y;
};
我希望将这些内容保存在一个容器中,以便按Item::y
排序,并确保每个条目都有唯一的Item::x
。我需要能够添加项目并删除顶部项目(即,y
值最小的项目。)
换句话说,可以做到这一点:
Container<Item> my_container;
my_container.insert(Item(0, 3.2));
my_container.insert(Item(2, 1.1));
my_container.insert(Item(0, 0.2));
my_container.insert(Item(1, 0.6));
my_container.insert(Item(3, 0.6));
my_container.insert(Item(0, 6.1));
for (auto &i : my_container)
std::cout << i.x << " " << i.y << std::endl;
理想情况下,这会产生:
1 0.6
3 0.6
2 1.1
0 6.1
起初,我使用std::set<Item>
并使用了确保item_1.y < item_2.y
的比较功能,但这不允许在item_1.y == item_2.y
但item_1.x != item_2.x
时添加项目。
有什么建议吗?谢谢。
更新
我决定查看Boost Multi-Index,因为我有Boost可用。我几乎有一个解决方案(使用Joaquín的答案):
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
using namespace boost::multi_index;
struct Item
{
Item(int i, float j) : x(i), y(j) {}
int x;
float y;
};
typedef multi_index_container<
Item,
indexed_by<
ordered_non_unique<member<Item,float,&Item::y> >,
ordered_unique<member<Item,int,&Item::x> >
>
> my_container_t;
int main()
{
my_container_t mc;
mc.insert(Item(0, 3.2));
mc.insert(Item(2, 1.1));
mc.insert(Item(0, 0.2));
mc.insert(Item(1, 0.6));
mc.insert(Item(3, 0.6));
mc.insert(Item(0, 6.1));
const my_container_t::nth_index<0>::type& y_index = mc.get<0>();
// Print
for (auto &i : y_index)
std::cout << i.x << " " << i.y << std::endl;
return 0;
}
该程序的输出是:
1 0.6
3 0.6
2 1.1
0 3.2
这几乎是我想要的。请注意,插入x = 0的项目不会使用该索引替换容器中的上一项。另外,另外,删除和返回容器中的顶部项目的最佳方法是什么。这样的事情就足够了:
Item pop(my_container_t &mc)
{
my_container_t::nth_index<0>::type& container = mc.get<0>();
auto item = *container.begin();
container.erase(container.begin());
return item;
}
答案 0 :(得分:4)
您需要两个容器:一个用于确保x
的唯一性,另一个用于在y
然后x
上提供排序。
boost
multi_index
容器可以同时执行这两项操作,但可能会过度。
正在使用set
或unordered_set
个x
个值,并丢弃已存在的内容。
按set
订购y
个元素,然后x
(std::tie(y,x)<std::tie(o.y,o.x)
是最简单,最安全的C ++ 11方式)或multiset
由y
订购,以维持秩序。我自己更喜欢set
s到multiset
,但这可能只是一个角色缺陷。
答案 1 :(得分:2)
与其他人所说的相反,我不考虑使用Boost.MultiIndex overkill:这正是lib设计的那种情况。
using namespace boost::multi_index;
typedef multi_index_container<
Item,
indexed_by<
ordered_non_unique<member<Item,float,&Item::y> >,
ordered_unique<member<Item,int,&Item::x> >
>
> my_container_t;