Come posso invertire un vettore C ++?


144

Esiste una funzione vettoriale integrata in C ++ per invertire un vettore in atto?

O devi semplicemente farlo manualmente?

Risposte:


251

C'è una funzione std::reversein algorithmintestazione per questo scopo.

#include <vector>
#include <algorithm>

int main() {
  std::vector<int> a;
  std::reverse(a.begin(), a.end());
  return 0;
}

Potresti spiegare come invertire il vettore dei vettori? Voglio che v [0] sia scambiato con v [v.size () - 1] e l'ordine dell'elemento v [0] [i] rimanga così com'è. Questo è simile alla modifica dell'ordine delle righe (se un vettore è visto come una matrice). Se un vettore è definito come: vettore <vettore <int>> v; reverse (v.begin (), v.end ()) non lo inverte. TIA!
Vikas Goel,

@VikasGoel infatti lo snippet che suggerisci dovrebbe funzionare. Forse c'è qualche altro problema?
Ivaylo Strandjev,

45

Tutti i contenitori offrono una vista invertita del loro contenuto con rbegin()e rend(). Queste due funzioni restituiscono i cosiddetti iteratori inversi , che possono essere utilizzati come quelli normali, ma sembrerà che il contenitore sia effettivamente invertito.

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

Esempio live su Ideone . Produzione:

1->2->3->4->5
=============
5<-4<-3<-2<-1

1
che tuttavia non inverte il vettore sul posto. È possibile creare un nuovo vettore con std :: vector <T> v2 (v1.rbegin (), v1.rend ()); v2.swap (v1); che utilizzerebbe efficacemente la tua soluzione. Non vedo come sia più elegante o vantaggioso in alcun modo usare std :: reverse però.
CashCow,

17
@CashCow: Beh, per uno, è un no-op, è O (1). Inversione .. non così tanto. Il più delle volte, non hai davvero bisogno di un contenitore invertito, devi solo vederlo come invertito. In realtà, non riesco a pensare a una situazione in cui è effettivamente necessario un contenitore invertito che non può essere risolto con iteratori inversi.
Xeo,

4
@CashCow: l'eleganza non è sempre vera eleganza. Nella maggior parte dei casi nella mia carriera professionale, avevo solo bisogno di una visione inversa, ma non di un vettore invertito. E in tutti questi casi, le prestazioni subirebbero del tutto inutilmente se si creassero più copie o si trasformasse l'ordine. Vorresti anche std::sortun vettore di 1000 elementi, se solo avessi bisogno della top-10 in un ordine non specificato, perché è più elegante di std::partition? Questa è la scuola di pensiero che paralizza la mia esperienza su PC oggi come 15 anni fa, con la differenza che vengono sprecati ancora più cicli, miliardi di loro.
Sebastian Mach,

print_rangenon è corretto: non funzionerà quando viene superato l'intervallo vuoto .
Nawaz,

quindi la grande domanda è: cosa farà std::reverse(a.rbegin(), a.rend())? ; ^)
Orwellophile,

23

Puoi usare std::reversecosì

std::reverse(str.begin(), str.end());

5
È incredibile la differenza che fanno due minuti.
1919

2

Puoi anche usare al std::listposto di std::vector. listha un elenco di funzioni integrato :: reverse per invertire gli elementi.


3
std :: list dovrebbe essere preferito al vettore nell'unico caso specifico di inserimento di molti elementi in posizioni arbitrarie nella sequenza. Usare std :: list sul vettore solo perché invertirai la sequenza è una cattiva idea dal punto di vista delle prestazioni.
eozd,

0

Spesso il motivo per cui si desidera invertire il vettore è perché lo si riempie spingendo tutti gli elementi alla fine, ma in realtà li si ricevevano in ordine inverso. In tal caso è possibile invertire il contenitore mentre si procede utilizzando un dequeinvece e spingendolo direttamente sulla parte anteriore. (Oppure potresti inserire gli elementi nella parte anteriore con vector::insert(), ma sarebbe lento quando ci sono molti articoli perché deve mescolare tutti gli altri elementi per ogni inserimento.) Invece di:

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

Puoi invece fare:

std::deque<int> foo;
int nextItem;
while (getNext(nextItem)) {
    foo.push_front(nextItem);
}
// No reverse needed - already in correct order

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
}

1
Questa domanda di otto anni ha bisogno di un'altra risposta duplicata che non aggiunga nulla?
Blastfurnace,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.