Como inverter um vetor C ++?

144

Existe uma função de vetor embutida no C ++ para reverter um vetor no lugar?

Ou você apenas precisa fazer isso manualmente?

SirYakalot
fonte

Respostas:

251

Há uma função std::reverseno algorithmcabeçalho para esse fim.

#include <vector>
#include <algorithm>

int main() {
  std::vector<int> a;
  std::reverse(a.begin(), a.end());
  return 0;
}
Ivaylo Strandjev
fonte
Você poderia explicar como reverter o vetor de vetores? Quero que v [0] seja trocado por v [v.size () - 1] e a ordem do elemento v [0] [i] permaneça como está. É semelhante à alteração da ordem das linhas (se um vetor for visto como uma matriz). Se um vetor é definido como: vector <vector <int>> v; reverse (v.begin (), v.end ()) não o inverte. TIA!
Vikas Goel
@VikasGoel, de fato, o snippet que você sugere deve funcionar. Talvez haja algum outro problema?
Ivaylo Strandjev
45

Todos os contêineres oferecem uma visão invertida de seu conteúdo com rbegin()e rend(). Essas duas funções retornam os chamados iteradores reversos , que podem ser usados ​​como normais, mas parecerá que o contêiner 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(), "<-");
}

Exemplo ao vivo no Ideone . Resultado:

1->2->3->4->5
=============
5<-4<-3<-2<-1
Xeo
fonte
1
no entanto, isso não inverte o vetor no local. Você pode criar um novo vetor com std :: vector <T> v2 (v1.rbegin (), v1.rend ()); v2.swap (v1); que usaria efetivamente sua solução. Não vejo como é mais elegante ou vantajoso o uso de std :: reverse.
Cashcow
17
@CashCow: Bem, por um lado, é um no-op, é O (1). Invertendo .. nem tanto. Na maioria das vezes, você realmente não precisa de um contêiner invertido, só precisa vê- lo como invertido. Na verdade, não consigo pensar em uma situação em que você realmente precise de um contêiner invertido que não possa ser resolvido com iteradores reversos.
Xeo 16/01/12
4
@CashCow: Elegância nem sempre é elegância verdadeira. Na maioria dos casos em minha carreira profissional, eu só precisava de uma visão invertida, mas não de um vetor invertido. E em todos esses casos, o desempenho seria totalmente desnecessário se você criar mais cópias ou transformar a ordem. Você também std::sortprecisaria de um vetor de 1000 elementos, se precisar apenas dos 10 primeiros em ordem não especificada, porque é mais elegante do que std::partition? Esta é a escola de pensamento que paralisa minha experiência com o PC hoje, como aconteceu há 15 anos, com a diferença de que ainda são desperdiçados mais ciclos, bilhões deles.
Sebastian Mach
print_rangenão está correto: não funcionará quando o intervalo vazio for ultrapassado.
Nawaz
então a grande questão é: o que fará std::reverse(a.rbegin(), a.rend())? ; ^)
Orwellophile
23

Você pode usar std::reverseassim

std::reverse(str.begin(), str.end());
Chuck Norris
fonte
5
É incrível a diferença que dois minutos fazem.
jww 17/09/19
2

Você também pode usar em std::listvez de std::vector. listpossui uma função interna list :: reverse para reverter elementos.

Olá W
fonte
3
O std :: list deve ser preferido sobre o vetor no único caso específico de inserir muitos elementos em posições arbitrárias na sequência. Usar std :: list sobre vetor apenas porque você reverterá a sequência é uma má ideia em termos de desempenho.
eozd
0

Freqüentemente, o motivo pelo qual você deseja reverter o vetor é porque você o preenche pressionando todos os itens no final, mas realmente os recebe na ordem inversa. Nesse caso, você pode inverter o contêiner usando um dequebotão e empurrando-o diretamente na frente. (Ou vector::insert(), em vez disso, você pode inserir os itens na frente , mas isso seria lento quando houver muitos itens, pois é necessário embaralhar todos os outros itens para cada inserção.) Portanto, ao contrário de:

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

Você pode fazer:

std::deque<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_front(nextItem);
}
// No reverse needed - already in correct order
Arthur Tacca
fonte
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
fonte
1
Essa pergunta de oito anos de idade precisa de outra resposta duplicada que não acrescente nada?
Blastfurnace