C++ 对两个不同字段进行排序并确定其唯一性的容器
假设我定义了一个类型,例如C++ 对两个不同字段进行排序并确定其唯一性的容器,c++,map,set,containers,C++,Map,Set,Containers,假设我定义了一个类型,例如 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.inser
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;
起初,我使用带有比较函数的std::set
,确保item_1.y
,但这不允许在item_1.y==item_2.y
但item_1.x!=项目2.x
有什么建议吗?多谢各位
更新
我决定研究Boost多索引,因为我有可用的Boost。我几乎有了一个解决方案(使用Joaquin下面的答案):
这几乎就是我想要的。请注意,插入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;
}
项目pop(my_container_t&mc)
{
my_container\u t::n_index::type&container=mc.get();
auto item=*container.begin();
container.erase(container.begin());
退货项目;
}
您需要两个容器:一个确保x
的唯一性,另一个在y
上提供订购,然后x
一个boost
multi_index
容器可以同时完成这两项任务,但可能会有过大的杀伤力
使用集合
或无序集合
的x
值,并丢弃已经存在的东西
拥有一组元素,按
y
然后x
排序(std::tie(y,x)您需要两个容器:一个确保x
的唯一性,另一个提供y
然后x
的排序
一个boost
multi_index
容器可以同时完成这两项任务,但可能会有过大的杀伤力
使用集合
或无序集合
的x
值,并丢弃已经存在的东西
< <代码> > <代码> >由<代码> y>代码>然后>代码> x>代码>(<代码> STD::Ty(y,x)
与别人所说的相反,我不考虑使用BooS.MulkObjultOff杀人:这正是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;
使用名称空间boost::multi_索引;
typedef多索引容器<
项目,,
索引<
有序非唯一,
有序_唯一
>
>我的集装箱;
>P>与别人所说的相反,我不考虑使用BooS.MulkObjultOff杀人:这正是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;
使用名称空间boost::multi_索引;
typedef多索引容器<
项目,,
索引<
有序非唯一,
有序_唯一
>
>我的集装箱;
您的示例有6个输入和4个输出,这令人困惑。@MooingDuck只有4个输出,因为带有x=0
的项被添加了三次。很像一个集合,最后两个项没有添加到容器中,因为带有x=0
的项已经在容器中。为什么不插入项(0,4.7)
overwriteItem(0,3.2)
?@MarkRansom抱歉,这是一个错误,我已经编辑了这个问题。假设他使用自己的自定义容器,他不能只更改容器的insert函数的逻辑,从而确定是否添加该项(基于x的值)以及在容器中的位置吗(基于y的值)?您的示例有6个输入和4个输出,这令人困惑。@MooningDuck只有4个输出,因为带有x=0
的项被添加了三次。很像一个集合,最后两个项没有添加到容器中,因为带有x=0
的项已经在容器中。为什么不插入项(0,4.7)
overwriteItem(0,3.2)
?@MarkRansom抱歉,这是一个错误,我已经编辑了这个问题。假设他使用自己的自定义容器,他不能只更改容器的insert函数的逻辑,从而确定是否添加该项(基于x的值)以及在容器中的位置吗(基于y的值)?
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;
}
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;