214

Is there a built-in vector function in C++ to reverse a vector in place?

Or do you just have to do it manually?

Sneaky Polar Bear
  • 1,611
  • 2
  • 17
  • 29
Dollarslice
  • 9,917
  • 22
  • 59
  • 87

5 Answers5

356

There's a function std::reverse in the algorithm header for this purpose.

#include <vector>
#include <algorithm>

int main() {
  std::vector<int> a;
  std::reverse(a.begin(), a.end());
  return 0;
}
Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
  • 1
    Could you explain how to reverse vector of vectors? I want v[0] to be swapped with v[v.size()-1] and the order of v[0][i] element remain as it is. This is similar to changing order of rows (if a vector is viewed as a Matrix). If a vector is defined as: vector > v; reverse(v.begin(), v.end()) doesn't reverse it. TIA! – Coder Jan 14 '16 at 20:30
  • @VikasGoel in fact the snippet you suggest should work. Maybe there is some other problem? – Ivaylo Strandjev Jan 14 '16 at 22:23
  • you can also keep the elements in reverse order, but then iterate backwards: for(auto i=a.end(); i!=a.begin();i--) {...} although that can be tricky due to off-by-one errors. so using rbegin() and rend() like others suggest is better – mo FEAR May 18 '22 at 17:59
54

All containers offer a reversed view of their content with rbegin() and rend(). These two functions return so-calles reverse iterators, which can be used like normal ones, but it will look like the container is actually reversed.

#include <vector>
#include <iostream>

template<class InIt>
void print_range(InIt first, InIt last, char const* delim = "\n"){
  --last;
  for(; first != last; ++first){
    std::cout << *first << delim;
  }
  std::cout << *first;
}

int main(){
  int a[] = { 1, 2, 3, 4, 5 };
  std::vector<int> v(a, a+5);
  print_range(v.begin(), v.end(), "->");
  std::cout << "\n=============\n";
  print_range(v.rbegin(), v.rend(), "<-");
}

Live example on Ideone. Output:

1->2->3->4->5
=============
5<-4<-3<-2<-1
Xeo
  • 129,499
  • 52
  • 291
  • 397
  • 1
    that doesn't however reverse the vector in-place. You could create a new vector with std::vector v2( v1.rbegin(), v1.rend() ); v2.swap(v1); which would effectively use your solution. I don't see how it is more elegant or advantageous in any way to using std::reverse though. – CashCow Jan 16 '12 at 10:45
  • 20
    @CashCow: Well, for one, it's a no-op, it's O(1). Reversing.. not so much. Most of the time, you don't really need a reversed container, you only need to *see* it as reversed. In fact, I can't think of a situation where you actually need a reversed container that can't be solved with reverse iterators. – Xeo Jan 16 '12 at 10:54
  • 5
    @CashCow: Elegance is not always true elegance. In most cases in my professional career, I just needed a reversed view, but not a reversed vector. And in all those cases, performance would suffer totally needlessy if you'd create more copies or transform the ordering. Would you also `std::sort` a 1000 element vector, if you just need the top-10 in unspecified order, because it is more elegant than `std::partition`? This is the school of thought that cripples my PC experience today as it did 15 years ago, with the difference that yet more cycles are wasted, billions of them. – Sebastian Mach Jan 17 '12 at 12:04
  • `print_range` is not correct: it will not work when *empty* range is passed. – Nawaz Dec 05 '13 at 09:05
  • so the big question is, what will `std::reverse(a.rbegin(), a.rend())` do? ;^) – Orwellophile May 27 '19 at 13:00
  • nitpick: `std::forward_list` is a container that doesn't have `rbegin rend` – Caleth Feb 03 '20 at 09:38
  • @Orwellophile the same as `std::reverse(a.begin(), a.end())` but with the arguments to `swap` (via `iter_swap`) effectively switched – Caleth Feb 03 '20 at 09:39
  • @caleth either sounds suspiciously like two `std::reverse`s make a `std::forward`. **the scary thing:** that might even compile and function correctly. – Orwellophile Mar 03 '20 at 03:33
  • @Orwellophile No, I mean that instead of `swap(first_element, last_element)` etc it's `swap(last_element, first_element)` – Caleth Mar 03 '20 at 08:24
  • @Xeo an example where you actually need to compute the reversed vector is when you use an API whose implementation you cannot change. – billx Sep 24 '21 at 09:03
28

You can use std::reverse like this

std::reverse(str.begin(), str.end());
Chuck Norris
  • 15,207
  • 15
  • 92
  • 123
3

Often the reason you want to reverse the vector is because you fill it by pushing all the items on at the end but were actually receiving them in reverse order. In that case you can reverse the container as you go by using a deque instead and pushing them directly on the front. (Or you could insert the items at the front with vector::insert() instead, but that would be slow when there are lots of items because it has to shuffle all the other items along for every insertion.) So as opposed to:

std::vector<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_back(nextItem);
}
std::reverse(foo.begin(), foo.end());

You can instead do:

std::deque<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_front(nextItem);
}
// No reverse needed - already in correct order
Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49
  • the downside is that the elements are no longer contiguous in memory like a vector, so you can't use .data() – mo FEAR May 18 '22 at 17:56
0

You can also use std::list instead of std::vector. list has a built-in function list::reverse for reversing elements.

Ajay
  • 18,086
  • 12
  • 59
  • 105
Hello W
  • 639
  • 8
  • 17
  • 6
    std::list should be preferred over vector in the only specific case of inserting many elements into arbitrary positions in the sequence. Using std::list over vector just because you will reverse the sequence is a bad idea performance-wise. – eozd May 15 '18 at 13:59