Какой самый умный способ добавить в начале вектора два последних элемента самого вектора и добавить в конце ветора первые два элемента вектора? Я имею в виду, если мой стартовый вектор
v = 1 2 3 4 5 6 7 8 9
Мне нужно, чтобы это стало
v = 8 9 1 2 3 4 5 6 7 8 9 1 2
Во-первых, если контейнер будет большим, то рассмотрим использование deque
вместо vector
. Это более эффективно для добавления в начале.
Для vector
вы не можете вставлять элементы из vector
в начало, потому что первое, что происходит, - это все, что переносится в вектор (и все итераторы и ссылки на эти элементы недействительны). Таким образом, вам нужно либо скопировать элементы из вектора, либо вам нужно поместить элементы вставки в начале, а затем скопировать-присваивать им. Предполагая, что тип int
, я пойду с первым:
if (v.size() >= 2) {
int tmp[] = {*(v.end() - 2), *(v.end() - 1)};
v.insert(v.begin(), tmp, tmp + 2);
tmp[0] = v[2]; tmp[1] = v[3];
v.insert(v.end(), tmp, tmp + 2);
}
Альтернативно, это использует больше памяти, но может быть легче читать. В качестве бонуса он дает сильную гарантию исключения даже с типами, которые может создавать броузер. Мой код выше можно сделать, чтобы предложить сильную гарантию, добавив вызов для reserve
, но только потому, что int
является тривиальным типом:
if (v.size() >= 2) {
std::vector<int> new_v;
new_v.reserve(v.size() + 4);
new_v.insert(new_v.end(), v.end() - 2, v.end());
new_v.insert(new_v.end(), v.begin(), v.end());
new_v.insert(new_v.end(), v.begin(), v.begin() + 2);
v.swap(new_v);
}
Для deque
вам не нужно хранить какие-либо элементы вне контейнера, если вы используете ссылку вместо итератора для доступа к ним. Опять же, это дает только основную гарантию исключения.
if (v.size() >= 2) {
v.push_front(v.back());
v.push_front(*&(v.end() - 1));
v.push_back(*&(v.begin() + 2));
v.push_back(*&(v.begin() + 3));
}
6 7 1 2 3 4 5 6 7 8 9 1 2
без добавленной строки в vector
части работает. Мне нужна эта линия?
Мои пять центов
std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
v.insert( v.end(), { v[0], v[1], v[v.size() - 2], v[v.size() - 1] } );
std::rotate( v.begin(), std::prev( v.end(), 2 ), v.end() );
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
Используя функцию vector :: insert для диапазонов. Легче сначала вставить первые два элемента в конец.
v.insert(v.end(), v.begin(), v.begin()+2);
v.insert(v.begin(), v.end()-2, v.end());
Изменение: это неопределенное поведение.
vector::insert()
?