Question Concaténation de deux vecteurs std :: vecteurs


Comment puis-je concaténer deux std::vectors?


481
2017-10-14 15:46


origine


Réponses:


vector1.insert( vector1.end(), vector2.begin(), vector2.end() );

546
2017-10-14 15:48



J'utiliserais le insérer une fonction, quelque chose comme:

vector<int> a, b;
//fill with data
b.insert(b.end(), a.begin(), a.end());

118
2017-10-14 15:48



Si vous utilisez C ++ 11 et souhaitez déplacer les éléments plutôt que de simplement les copier, vous pouvez utiliser std :: move_iterator (http://en.cppreference.com/w/cpp/iterator/move_iterator) avec insert (ou copie):

#include <vector>
#include <iostream>
#include <iterator>

int main(int argc, char** argv) {
  std::vector<int> dest{1,2,3,4,5};
  std::vector<int> src{6,7,8,9,10};

  // Move elements from src to dest.
  // src is left in undefined but safe-to-destruct state.
  dest.insert(
      dest.end(),
      std::make_move_iterator(src.begin()),
      std::make_move_iterator(src.end())
    );

  // Print out concatenated vector.
  std::copy(
      dest.begin(),
      dest.end(),
      std::ostream_iterator<int>(std::cout, "\n")
    );

  return 0;
}

Cela ne sera pas plus efficace pour l'exemple avec ints, car les déplacer n'est pas plus efficace que de les copier, mais pour une structure de données avec des déplacements optimisés, il est possible d'éviter de copier un état inutile:

#include <vector>
#include <iostream>
#include <iterator>

int main(int argc, char** argv) {
  std::vector<std::vector<int>> dest{{1,2,3,4,5}, {3,4}};
  std::vector<std::vector<int>> src{{6,7,8,9,10}};

  // Move elements from src to dest.
  // src is left in undefined but safe-to-destruct state.
  dest.insert(
      dest.end(),
      std::make_move_iterator(src.begin()),
      std::make_move_iterator(src.end())
    );

  return 0;
}

Après le déplacement, l'élément de src est laissé dans un état indéfini mais sûr à détruire, et ses anciens éléments ont été transférés directement au nouvel élément de dest à la fin.


116
2018-02-23 18:11



Ou vous pouvez utiliser:

std::copy(source.begin(), source.end(), std::back_inserter(destination));

Ce modèle est utile si les deux vecteurs ne contiennent pas exactement le même type de chose, car vous pouvez utiliser quelque chose à la place de std :: back_inserter pour convertir un type en un autre.


70
2017-10-14 16:20



Avec C ++ 11, je préférerais suivre pour ajouter le vecteur b à un:

std::move(b.begin(), b.end(), std::back_inserter(a));

quand a et b ne se chevauchent pas, et b ne va plus être utilisé.


32
2018-06-12 07:53



std::vector<int> first;
std::vector<int> second;

first.insert(first.end(), second.begin(), second.end());

30
2017-10-14 15:48



Je préfère celui qui est déjà mentionné:

a.insert(a.end(), b.begin(), b.end());

Mais si vous utilisez C ++ 11, il existe un moyen plus générique:

a.insert(std::end(a), std::begin(b), std::end(b));

En outre, ne fait pas partie d'une question, mais il est conseillé d'utiliser reserve avant d'ajouter pour de meilleures performances. Et si vous êtes en train de concaténer le vecteur avec lui-même, sans le réserver échoue, vous devriez toujours reserve.


Donc, fondamentalement, ce dont vous avez besoin:

template <typename T>
void Append(std::vector<T>& a, const std::vector<T>& b)
{
    a.reserve(a.size() + b.size());
    a.insert(a.end(), b.begin(), b.end());
}

18
2018-06-10 09:27