Есть ли лучший способ перемещения элементов в векторе - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть элемент 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);

не сработает.

Мое текущее решение делает некоторые перестановки, но без выделения новой памяти

auto newElement = vecElements.rbegin();
for (auto currentPos = vecElements.size()-1; currentPos != pos; --currentPos)
    newElement->swap(*(newElement + 1)); // reverseIterator +1 = element before

Чтобы прояснить это, потому что @NathanOliver спросил ... оставшееся упорядочение вектора должно быть сохранено.

Is Есть ли лучший способ сделать это?

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Вы можете использовать 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

Возможно, вы сможете настроить используемые итераторы, если вам нужно переместить элемент, который не находится в конце.

0 голосов
/ 01 апреля 2020

Переместите элемент из вектора, сотрите элемент, затем вставьте. Это гарантированно не перераспределит, поскольку это происходит только тогда, когда size() > capcity(), и это не может произойти здесь, потому что первое удаление гарантирует, что size() <= capcity() - 1

В случае перемещения последнего элемента это будет выглядеть как

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

Таким образом, это обойдется вам в два шага и без перераспределения.

...