有没有更好的方法在向量中移动元素
Is there a better way of moving elements in a vector
我有 std::vector 个元素,想将一个元素移动到指定位置。
我已经有了解决方案,但我很好奇,如果有更好的方法。
假设我想将最后一个元素移动到索引位置;
我可以做一个
auto posToInsert = vecElements.begin();
std::advance(posToInsert, pos);
vecElements.insert(posToInsert, *m_vecRows.rbegin());
vecElements.erase(m_vecRows.rbegin());
但这会重新分配内存。
可惜了
std::move(vecElements.rbegin(), vecElements.rbegin(), posToInsert);
行不通。
我当前的解决方案进行了一些交换,但没有新的内存分配
auto newElement = vecElements.rbegin();
for (auto currentPos = vecElements.size()-1; currentPos != pos; --currentPos)
newElement->swap(*(newElement + 1)); // reverseIterator +1 = element before
澄清一下,因为@NathanOliver 询问...应保留矢量的其余顺序。
有更好的方法吗?
将元素移出向量,擦除元素,然后插入。这保证不会重新分配,因为这只会在 size() > capcity()
时发生,而不会在这里发生,因为首先擦除保证 size() <= capcity() - 1
在移动最后一个元素的情况下,看起来像
auto temp = std::move(vecElements.back())
vecElements.erase(vecElements.rbegin());
vecElements.insert(posToInsert, std::move(temp));
因此,这花费了您两次移动且没有重新分配。
你可以使用 std::rotate
:
#include <algorithm>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> values{1, 2, 3, 4, 5};
std::rotate(values.begin()+2, values.end()-1, values.end());
for(int i: values)
std::cout << i << " ";
std::cout << "\n";
}
输出:
1 2 5 3 4
如果您需要移动不在末尾的元素,您可以调整使用的迭代器。
我有 std::vector 个元素,想将一个元素移动到指定位置。 我已经有了解决方案,但我很好奇,如果有更好的方法。
假设我想将最后一个元素移动到索引位置;
我可以做一个
auto posToInsert = vecElements.begin();
std::advance(posToInsert, pos);
vecElements.insert(posToInsert, *m_vecRows.rbegin());
vecElements.erase(m_vecRows.rbegin());
但这会重新分配内存。
可惜了
std::move(vecElements.rbegin(), vecElements.rbegin(), posToInsert);
行不通。
我当前的解决方案进行了一些交换,但没有新的内存分配
auto newElement = vecElements.rbegin();
for (auto currentPos = vecElements.size()-1; currentPos != pos; --currentPos)
newElement->swap(*(newElement + 1)); // reverseIterator +1 = element before
澄清一下,因为@NathanOliver 询问...应保留矢量的其余顺序。
有更好的方法吗?
将元素移出向量,擦除元素,然后插入。这保证不会重新分配,因为这只会在 size() > capcity()
时发生,而不会在这里发生,因为首先擦除保证 size() <= capcity() - 1
在移动最后一个元素的情况下,看起来像
auto temp = std::move(vecElements.back())
vecElements.erase(vecElements.rbegin());
vecElements.insert(posToInsert, std::move(temp));
因此,这花费了您两次移动且没有重新分配。
你可以使用 std::rotate
:
#include <algorithm>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> values{1, 2, 3, 4, 5};
std::rotate(values.begin()+2, values.end()-1, values.end());
for(int i: values)
std::cout << i << " ";
std::cout << "\n";
}
输出:
1 2 5 3 4
如果您需要移动不在末尾的元素,您可以调整使用的迭代器。