将向量元素移动到向量的后面

Vio*_*ffe 9 c++ vector stdvector

有没有更好的方法(更快或代码更少的符号)比擦除元素并重新添加到后面?

template <typename T>
void moveItemToBack(std::vector<T>& v, size_t itemIndex)
{
   T tmp(v[itemIndex]);
   v.erase(v.begin() + itemIndex);
   v.push_back(tmp);
}
Run Code Online (Sandbox Code Playgroud)

Bla*_*ace 34

您可以使用std::rotate标准库执行此操作.由于这不会改变矢量大小,因此也不会触发重新分配.你的功能看起来像这样:

template <typename T>
void moveItemToBack(std::vector<T>& v, size_t itemIndex)
{
    auto it = v.begin() + itemIndex;
    std::rotate(it, it + 1, v.end());
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是 Stepanov(设计 STL)的建议:http://www.stepanovpapers.com/notes.pdf,pg。154. (2认同)
  • @imallett 你是对的。这个答案确实保留了移动项目以外的元素顺序,而另一个答案则没有。如前所述,这个问题并不清楚这是否是一项要求。保持秩序的成本更高。 (2认同)

Nik*_*iou 8

可能是最快的方法,就是将它与最后一个元素交换

template <typename T>
void moveItemToBack(std::vector<T>& v, size_t itemIndex)
{
   std::swap(v[itemIndex], v.back()); // or swap with *(v.end()-1)
}
Run Code Online (Sandbox Code Playgroud)

一次操作!Ofcourse std::swap必须与之合作T

  • 这是一个明显的解决方案,但它改变了项目的顺序,而不仅仅是将一个项目移动到最后. (5认同)

Bri*_*ian 5

您可以避免额外的变量。

v.push_back(v[itemIndex]);
v.erase(v.begin() + itemIndex);
Run Code Online (Sandbox Code Playgroud)

如果您经常从向量中间删除并且可以重写您的代码使其不需要随机访问,您可以通过使用链表 ( std::list)来提高效率。

  • 这样做可能会影响性能。在“擦除”之前执行“push_back”会暂时增加向量的大小并可能导致重新分配。 (5认同)