我看过一些特殊情况下可以使用std::rotate
或与搜索算法之一相结合,但通常:当有一个N项的向量并希望编写如下函数时:
void move( int from, int count, int to, std::vector<int>& numbers );
我一直在思考如何创建一个新向量+std::copy
或插入/擦除的组合,但我不能说我得到了一些漂亮和优雅的解决方案。
在得出任何结论之前,剖析代码总是很重要的。 vector
的数据存储连续性可能会带来比基于节点的容器更显著的缓存优势。 因此,也许你可以尝试直接处理:
void move_range(size_t start, size_t length, size_t dst, std::vector<T> & v)
{
const size_t final_dst = dst > start ? dst - length : dst;
std::vector<T> tmp(v.begin() + start, v.begin() + start + length);
v.erase(v.begin() + start, v.begin() + start + length);
v.insert(v.begin() + final_dst, tmp.begin(), tmp.end());
}
在C++11中,你需要将第一行和第三行的迭代器封装到std::make_move_iterator
中。
(要求是dst
不能位于[start,start + length)
之内,否则问题就没有明确定义。)
length >= 0
,但那是自动的。 - Kerrek SB根据向量的大小和涉及的范围,这种方法可能比执行复制/删除/插入更加经济实惠。
template <typename T>
void move_range(size_t start, size_t length, size_t dst, std::vector<T> & v)
{
typename std::vector<T>::iterator first, middle, last;
if (start < dst)
{
first = v.begin() + start;
middle = first + length;
last = v.begin() + dst;
}
else
{
first = v.begin() + dst;
middle = v.begin() + start;
last = middle + length;
}
std::rotate(first, middle, last);
}
std::swap
以获得更高效的“移动”。要利用此功能,您需要执行类似以下操作:std::vector<Foo> new_vec;
Foo tmp;
for (/* each Foo&f in old_vec, first section */) {
swap (f, tmp);
new_vec .push_back (tmp);
}
for (/* each Foo&f in old_vec, second section */) {
swap (f, tmp);
new_vec .push_back (tmp);
}
for (/* each Foo&f in old_vec, third section */) {
swap (f, tmp);
new_vec .push_back (tmp);
}
swap (new_vec, old_vec);
swap
的C++11也可能产生良好的结果。Foo
没有移动语义或优化的swap
,则链表或某些聪明的序列类型可能更好。std::vector<Foo> move (std::vector<Foo> old_vec, ...)`
std::swap
。将swap(Foo&,Foo&)
放置在与Foo
相同的命名空间中是正常的,并且通过请求std::swap
,您无法让ADL找到正确的重载。 - visitorswap
特化放入 std
命名空间中。 - spraffusing std::swap; swap(x,y);
这样,就会使用 ADL(这是好的),并使用 std::swap 作为后备方案。顺便说一下,这基本上就是 boost::swap 所做的。 - sellibitze
std::list
而不是std::vector
等数据结构实现更加高效。请注意保持原文意思,同时使内容更加通俗易懂。 - Frerich Raabemove
函数是否应该正常工作? - Frerich Raaberotate
是最好的方法:https://dev59.com/b2Uq5IYBdhLWcg3wV_Ai#14580001 - Violet Giraffe