Wie kehre ich einen C ++ - Vektor um?


144

Gibt es in C ++ eine integrierte Vektorfunktion, um einen vorhandenen Vektor umzukehren?

Oder müssen Sie es nur manuell tun?

Antworten:


251

Zu diesem Zweck enthält std::reverseder algorithmHeader eine Funktion .

#include <vector>
#include <algorithm>

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

Können Sie erklären, wie man den Vektor von Vektoren umkehrt? Ich möchte, dass v [0] gegen v [v.size () - 1] ausgetauscht wird und die Reihenfolge des v [0] [i] -Elements unverändert bleibt. Dies ähnelt dem Ändern der Zeilenreihenfolge (wenn ein Vektor als Matrix betrachtet wird). Wenn ein Vektor definiert ist als: vector <vector <int>> v; reverse (v.begin (), v.end ()) kehrt es nicht um. TIA!
Vikas Goel

@VikasGoel in der Tat sollte das von Ihnen vorgeschlagene Snippet funktionieren. Vielleicht gibt es ein anderes Problem?
Ivaylo Strandjev

45

Alle Container bieten eine umgekehrte Ansicht ihres Inhalts mit rbegin()und rend(). Diese beiden Funktionen geben sogenannte Reverse-Iteratoren zurück , die wie normale verwendet werden können, aber es sieht so aus, als ob der Container tatsächlich umgekehrt ist.

#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-Beispiel auf Ideone . Ausgabe:

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

1
das kehrt den Vektor jedoch nicht an Ort und Stelle um. Sie können einen neuen Vektor mit std :: vector <T> v2 (v1.rbegin (), v1.rend ()) erstellen. v2.swap (v1); die effektiv Ihre Lösung nutzen würde. Ich sehe jedoch nicht, wie eleganter oder vorteilhafter es ist, std :: reverse zu verwenden.
CashCow

17
@CashCow: Zum einen ist es ein No-Op, es ist O (1). Umkehren .. nicht so sehr. Meistens brauchen Sie keinen umgekehrten Container, Sie müssen ihn nur als umgekehrt ansehen . Tatsächlich kann ich mir keine Situation vorstellen, in der Sie tatsächlich einen umgekehrten Container benötigen, der mit umgekehrten Iteratoren nicht gelöst werden kann.
Xeo

4
@CashCow: Eleganz ist nicht immer wahre Eleganz. In den meisten Fällen meiner beruflichen Laufbahn brauchte ich nur eine umgekehrte Ansicht, aber keinen umgekehrten Vektor. In all diesen Fällen würde die Leistung völlig unnötig leiden, wenn Sie mehr Kopien erstellen oder die Reihenfolge ändern würden. Würden Sie auch std::sorteinen 1000-Elemente-Vektor verwenden, wenn Sie nur die Top-10 in nicht spezifizierter Reihenfolge benötigen, weil sie eleganter ist als std::partition? Dies ist die Denkschule, die meine PC-Erfahrung heute wie vor 15 Jahren lähmt, mit dem Unterschied, dass noch mehr Zyklen verschwendet werden, Milliarden davon.
Sebastian Mach

print_rangeist nicht korrekt: Es funktioniert nicht, wenn der leere Bereich überschritten wird.
Nawaz

Die große Frage ist also, was wird std::reverse(a.rbegin(), a.rend())tun? ; ^)
Orwellophile

23

Sie können verwendet werden, std::reversewie dies

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

5
Es ist erstaunlich, welchen Unterschied zwei Minuten machen.
JWW

2

Sie können auch std::listanstelle von verwenden std::vector. listhat eine eingebaute Funktionsliste :: reverse zum Umkehren von Elementen.


3
std :: list sollte dem Vektor vorgezogen werden, wenn nur viele Elemente an beliebigen Positionen in der Sequenz eingefügt werden. Die Verwendung von std :: list über Vektor, nur weil Sie die Reihenfolge umkehren, ist in Bezug auf die Leistung eine schlechte Idee.
Eozd

0

Oft möchten Sie den Vektor umkehren, weil Sie ihn füllen, indem Sie alle Elemente am Ende weiterschieben, sie aber tatsächlich in umgekehrter Reihenfolge erhalten haben. In diesem Fall können Sie den Container im Laufe der Zeit umkehren, indem Sie stattdessen a dequeverwenden und ihn direkt auf die Vorderseite schieben. (Oder Sie könnten vector::insert()stattdessen die Elemente an der Vorderseite mit einfügen , aber das wäre langsam, wenn es viele Elemente gibt, da alle anderen Elemente bei jeder Einfügung gemischt werden müssen.) Im Gegensatz zu:

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

Sie können stattdessen Folgendes tun:

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
Benötigt diese acht Jahre alte Frage eine weitere doppelte Antwort, die nichts hinzufügt?
Blastfurnace
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.