【问题标题】:Is there a better way of moving elements in a vector有没有更好的方法来移动向量中的元素
【发布时间】:2020-04-01 16:26:12
【问题描述】:

我有一个 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 要求...应该保留向量的剩余顺序。

有没有更好的方法?

【问题讨论】:

  • 您是否关心您要移动到的位置的元素?如果没有,只需交换它们
  • 在文本中添加了一个说明......其他元素的顺序应该保持不变。
  • 尝试 -- 获取源位置的值,擦除源位置的元素,然后在目标位置插入该值。
  • 但这会重新分配内存 -- 我们要处理多少个元素?发生重新分配的问题是什么?通常,向量实施一种策略,其中重新分配的次数被最小化。并不是每次添加元素时都会进行重新分配。

标签: c++ vector move stdvector swap


【解决方案1】:

你可以使用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

输出: 1 2 5 3 4

如果您需要移动一个不在末尾的元素,您可能可以调整使用的迭代器。

【讨论】:

  • 谢谢,我忘记了轮换...并向 Sean Parent 深深鞠躬
【解决方案2】:

将元素移出向量,擦除元素,然后插入。这保证不会重新分配,因为只有在 size() &gt; capcity() 时才会发生这种情况,而这里不会发生这种情况,因为首先擦除保证 size() &lt;= capcity() - 1

在移动最后一个元素的情况下,看起来像

auto temp = std::move(vecElements.back())
vecElements.erase(vecElements.rbegin());
vecElements.insert(posToInsert, std::move(temp));

所以,这会花费您两次移动且无需重新分配。

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 2016-07-22
    • 2018-01-30
    • 2019-03-05
    • 1970-01-01
    • 2012-12-16
    • 2021-09-26
    • 1970-01-01
    • 2016-04-02
    相关资源
    最近更新 更多