207 votes

Comment inverser un vecteur C++ ?

Existe-t-il une fonction vectorielle intégrée en C++ pour inverser un vecteur en place ?

Ou devez-vous le faire manuellement ?

344voto

Ivaylo Strandjev Points 38924

Il y a une fonction std::reverse dans le algorithm à cette fin.

#include <vector>
#include <algorithm>

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

1 votes

Pourriez-vous expliquer comment inverser le vecteur des vecteurs ? Je veux que v[0] soit échangé avec v[v.size()-1] et que l'ordre de l'élément v[0][i] reste tel quel. Ceci est similaire au changement de l'ordre des lignes (si un vecteur est vu comme une matrice). Si un vecteur est défini comme : vector<vector<int> > v ; reverse(v.begin(), v.end()) ne l'inverse pas. TIA !

0 votes

@VikasGoel en fait le snippet que vous suggérez devrait fonctionner. Peut-être y a-t-il un autre problème ?

53voto

Xeo Points 69818

Tous les conteneurs offrent une voir de leur contenu avec rbegin() et rend() . Ces deux fonctions renvoient des so-calles itérateurs inversés qui peuvent être utilisés comme des conteneurs normaux, mais qui donneront l'impression que le conteneur est en fait inversé.

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

Exemple concret sur Ideone . Sortie :

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

1 votes

qui n'inverse cependant pas le vecteur in-place. Vous pourriez créer un nouveau vecteur avec std::vector<T> v2( v1.rbegin(), v1.rend() ) ; v2.swap(v1) ; ce qui utiliserait effectivement votre solution. Je ne vois pas en quoi elle est plus élégante ou plus avantageuse que l'utilisation de std::reverse.

20 votes

@CashCow : Eh bien, d'abord, c'est un no-op, c'est O(1). Inverser pas tant que ça. La plupart du temps, vous n'avez pas vraiment besoin d'un conteneur inversé, vous devez seulement voir comme étant inversé. En fait, je ne vois pas de situation où l'on ait réellement besoin d'un conteneur inversé qui ne puisse être résolu avec des itérateurs inversés.

5 votes

@CashCow : L'élégance n'est pas toujours la véritable élégance. Dans la plupart des cas de ma carrière professionnelle, j'avais juste besoin d'une vue inversée, mais pas d'un vecteur inversé. Et dans tous ces cas, la performance souffrirait totalement sans nécessité si vous créiez plus de copies ou transformiez l'ordonnancement. Pourriez-vous également std::sort un vecteur de 1000 éléments, si vous avez juste besoin des 10 premiers dans un ordre non spécifié, parce que c'est plus élégant que std::partition ? C'est l'école de pensée qui paralyse mon expérience sur PC aujourd'hui comme il y a 15 ans, à la différence qu'encore plus de cycles sont gaspillés, des milliards de cycles.

28voto

Chuck Norris Points 8240

Vous pouvez utiliser std::reverse comme ceci

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

3voto

Arthur Tacca Points 2979

Souvent, la raison pour laquelle vous voulez inverser le vecteur est que vous le remplissez en poussant tous les articles à la fin, mais que vous les recevez en fait dans l'ordre inverse. Dans ce cas, vous pouvez inverser le conteneur au fur et à mesure en utilisant la fonction deque à la place et en les poussant directement sur le front. (Ou vous pouvez insérer les éléments à l'avant avec vector::insert() à la place, mais cela serait lent lorsqu'il y a beaucoup d'éléments car il doit mélanger tous les autres éléments à chaque insertion). Donc, par opposition à :

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

Vous pouvez le faire à la place :

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

0voto

Hello W Points 189

Vous pouvez également utiliser std::list au lieu de std::vector . list a une fonction intégrée liste::reverse pour les éléments d'inversion.

6 votes

Std::list doit être préféré à vector dans le seul cas spécifique de l'insertion de nombreux éléments à des positions arbitraires dans la séquence. Utiliser std::list plutôt que vector simplement parce que vous allez inverser la séquence est une mauvaise idée en termes de performances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X