我有一个std :: vector元素,想将一个元素移动到指定位置。我已经有一个解决方案,但是如果有更好的方法,我很好奇。
假设我想将最后一个元素移到索引pos;
我可以做一个
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);
不做the俩。
我当前的解决方案进行了一些交换,但没有新的内存分配
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
:
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";
}
输出:try it
如果需要移动不位于结尾的元素,则可以调整使用的迭代器。