¿Cómo revierto un vector C ++?

144

¿Hay una función de vector incorporada en C ++ para revertir un vector en su lugar?

¿O solo tienes que hacerlo manualmente?

Sir Yakalot
fuente

Respuestas:

251

Hay una función std::reverseen el algorithmencabezado para este propósito.

#include <vector>
#include <algorithm>

int main() {
  std::vector<int> a;
  std::reverse(a.begin(), a.end());
  return 0;
}
Ivaylo Strandjev
fuente
¿Podría explicar cómo invertir el vector de vectores? Quiero que v [0] se intercambie con v [v.size () - 1] y el orden del elemento v [0] [i] permanezca como está. Esto es similar a cambiar el orden de las filas (si un vector se ve como una Matriz). Si un vector se define como: vector <vector <int>> v; reverse (v.begin (), v.end ()) no lo revierte. TIA!
Vikas Goel
@VikasGoel, de hecho, el fragmento que sugieres debería funcionar. Tal vez hay algún otro problema?
Ivaylo Strandjev
45

Todos los contenedores ofrecen una vista inversa de su contenido con rbegin()y rend(). Estas dos funciones devuelven iteradores inversos , que se pueden usar como los normales, pero parecerá que el contenedor está realmente invertido.

#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(), "<-");
}

Ejemplo en vivo en Ideone . Salida:

1->2->3->4->5
=============
5<-4<-3<-2<-1
Xeo
fuente
1
sin embargo, eso no invierte el vector en el lugar. Puede crear un nuevo vector con std :: vector <T> v2 (v1.rbegin (), v1.rend ()); v2.swap (v1); que efectivamente usaría su solución. Sin embargo, no veo cómo es más elegante o ventajoso usar std :: reverse.
CashCow
17
@CashCow: Bueno, por un lado, es un no-op, es O (1). Revertir ... no tanto. La mayoría de las veces, realmente no necesita un contenedor invertido, solo necesita verlo como invertido. De hecho, no puedo pensar en una situación en la que realmente necesites un contenedor invertido que no se pueda resolver con iteradores inversos.
Xeo
44
@CashCow: La elegancia no siempre es verdadera elegancia. En la mayoría de los casos en mi carrera profesional, solo necesitaba una vista inversa, pero no un vector inverso. Y en todos esos casos, el rendimiento se vería totalmente innecesario si crea más copias o transforma el pedido. ¿También sería std::sortun vector de 1000 elementos, si solo necesita el top 10 en un orden no especificado, porque es más elegante que std::partition? Esta es la escuela de pensamiento que paraliza mi experiencia de PC hoy como lo hizo hace 15 años, con la diferencia de que se desperdician aún más ciclos, miles de millones de ellos.
Sebastian Mach
print_rangeno es correcto: no funcionará cuando se pase el rango vacío .
Nawaz
entonces la gran pregunta es, ¿qué hará std::reverse(a.rbegin(), a.rend())? ; ^)
Orwellophile
23

Puedes usar std::reverseasí

std::reverse(str.begin(), str.end());
Chuck Norris
fuente
55
Es sorprendente la diferencia que hacen dos minutos.
jww
2

También puedes usar en std::listlugar de std::vector. listtiene una lista de funciones incorporada :: reverse para revertir elementos.

Hola w
fuente
3
std :: list debe preferirse sobre el vector en el único caso específico de insertar muchos elementos en posiciones arbitrarias en la secuencia. Usar std :: list sobre vector solo porque revertirá la secuencia es una mala idea en cuanto al rendimiento.
Eozd
0

A menudo, la razón por la que desea invertir el vector es porque lo llena presionando todos los elementos al final, pero en realidad los estaba recibiendo en orden inverso. En ese caso, puede invertir el contenedor a medida que avanza utilizando un dequelugar y empujándolos directamente en el frente. (O bien, podría insertar los elementos en la parte delantera con vector::insert(), pero eso sería lento cuando hay muchos elementos porque tiene que mezclar todos los demás elementos para cada inserción). Así que en lugar de:

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

En su lugar, puedes hacer:

std::deque<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_front(nextItem);
}
// No reverse needed - already in correct order
Arthur Tacca
fuente
0
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
int main()
{
    vector<int>v1;
    for(int i=0; i<5; i++)
        v1.push_back(i*2);
    for(int i=0; i<v1.size(); i++)
        cout<<v1[i];    //02468
    reverse(v1.begin(),v1.end());
    
    for(int i=0; i<v1.size(); i++)
        cout<<v1[i];   //86420
}
bashar
fuente
1
¿Esta pregunta de ocho años necesita otra respuesta duplicada que no agrega nada?
Horno de fuego el