对两个不同字段进行排序并确定其唯一性的容器
A container that sorts and determines uniqueness from two different fields
假设我定义了一个类型,比如
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多指数,因为我有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;
}
您需要两个容器:一个确保x
的唯一性,另一个在y
和x
上提供排序。
一个boost
multi_index
容器可以同时完成这两项工作,但可能有些过头了。
使用x
值中的set
或unordered_set
,并丢弃已经存在的内容。
让元素的set
按y
排序,然后按x
排序(std::tie(y,x)<std::tie(o.y,o.x)
是最简单和最安全的C++11方法),或者按y
排序multiset
,以维持秩序。我更喜欢set
而不是multiset
,但这可能只是性格上的缺陷。
与其他人所说的相反,我不认为使用Boost.MultiIndex过于夸张:这正是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;
相关文章:
- 二叉排序树无法编译
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- C++选择排序算法中的逻辑错误
- 使用C++程序合并排序没有得到正确的输出
- 计算排序向量的向量中唯一值的计数
- 排序算法c++
- 使用2个键的cpp-stl::优先级队列排序不正确
- 将结构向量排序为子组
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 如何对点云数据进行排序
- 对字符串进行排序时,在c++中处理sort()
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 下面是排序算法O(n)吗
- std::sort()函数无法对向量的一部分进行排序
- shell排序中的交换和比较
- clang格式:禁用排序包含
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- 有没有办法为集合指定不同的唯一性和排序标准
- 对两个不同字段进行排序并确定其唯一性的容器
- 对数组中的数字进行排序以找出唯一性