[英]Order a container by member with STL
Suppose I have some data stored in a container of unique_ptr
s: 假设我有一些数据存储在
unique_ptr
的容器中:
struct MyData {
int id; // a unique id for this particular instance
data some_data; // arbitrary additional data
};
// ...
std::vector<std::unique_ptr<MyData>> my_data_vec;
The ordering of my_data_vec
is important. my_data_vec
的顺序很重要。 Suppose now I have another vector of IDs of MyDatas: 假设我现在有另一个ID为MyDatas的向量:
std::vector<int> my_data_ids;
I now want to rearrange my_data_vec
such that the elements are in the sequence specified by my_data_ids
. 我现在想要重新排列
my_data_vec
,使得元素按照my_data_ids
指定的顺序my_data_ids
。 (Don't forget moving a unique_ptr
requires move-semantics with std::move()
.) (不要忘记移动
unique_ptr
需要使用std::move()
移动语义。)
What's the most algorithmically efficient way to achieve this, and do any of the STL algorithms lend themselves well to achieving this? 什么是实现这一目标的最具算法效率的方法,并且任何STL算法都能很好地实现这一目标吗? I can't see that
std::sort
would be any help. 我看不出
std::sort
会有任何帮助。
Edit: I can use O(n) memory space (not too worried about memory), but the IDs are arbitrary (in my specific case they are actually randomly generated). 编辑:我可以使用O(n)内存空间(不太担心内存),但ID是任意的(在我的特定情况下,它们实际上是随机生成的)。
my_data_ids
. my_data_ids
的索引。 std::unique_ptr<MyData>
based on their ID's index in that map. std::unique_ptr<MyData>
。 std::sort
to sort the my_data_vec
using that function object. std::sort
来使用该函数对象对my_data_vec
进行排序。 Here's a sketch of this: 这是一个草图:
// Beware, brain-compiled code ahead!
typedef std::vector<int> my_data_ids_type;
typedef std::map<int,my_data_ids_type::size_type> my_data_ids_map_type;
class my_id_comparator : public std::binary_function< bool
, std::unique_ptr<MyData>
, std::unique_ptr<MyData> > {
public:
my_id_comparator(const my_data_ids_map_type& my_data_ids_map)
: my_data_ids_map_(my_data_ids_map) {}
bool operator()( const std::unique_ptr<MyData>& lhs
, const std::unique_ptr<MyData>& rhs ) const
{
my_data_ids_map_type::const_iterator it_lhs = my_data_ids_map_.find(lhs.id);
my_data_ids_map_type::const_iterator it_rhs = my_data_ids_map_.find(rhs.id);
if( it_lhs == my_data_ids_map_.end() || it_rhs == my_data_ids_map_.end() )
throw "dammit!"; // whatever
return it_lhs->second < it_rhs->second;
}
private
my_data_ids_map_type& my_data_ids_map_;
};
//...
my_data_ids_map_type my_data_ids_map;
// ...
// populate my_data_ids_map with the IDs and their indexes from my_data_ids
// ...
std::sort( my_data_vec.begin(), my_data_vec.end(), my_id_comparator(my_data_ids_map) );
If memory is scarce, but time doesn't matter, you could do away with the map and search the IDs in the my_data_ids
vector for each comparison. 如果内存不足,但时间无关紧要,您可以取消地图并搜索
my_data_ids
向量中的ID以进行每次比较。 However, you would have to be really desperate for memory to do that, since two linearly complex operations per comparison are going to be quite expensive. 但是,你必须非常渴望内存才能做到这一点,因为每次比较的两个线性复杂操作将非常昂贵。
Why don't you try moving the data into a STL Set ? 为什么不尝试将数据移动到STL集中? you need only to implement the comparison function, and you will end up with a perfectly ordered set of data very fast.
你只需要实现比较功能,你最终会得到一组完美有序的数据。
为什么不直接使用map<int, unique_ptr<MyData>>
(或multimap
)?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.