Introduction : Pourquoi concaténer des vecteurs et pourquoi est-ce difficile ?
\n\nBonjour, collègue ! Si tu as déjà écrit du code C++ qui traite des listes de données, tu as sûrement rencontré ce problème : « J’ai deux std::vector, comment en faire un seul ? » Cette question est un véritable hit sur Stack Overflow (des milliers de vues !), et ce n’est pas pour rien. À première vue, on se dit : qu’est-ce qu’il y a de si compliqué ? vector1 + vector2, comme en Python ? Et bien non. En C++, l’opérateur + n’est pas défini pour les vecteurs. Il faut ruser.
Aujourd’hui, nous allons voir en détail la concaténation de deux std::vectors. Je vais te montrer 3 méthodes éprouvées, t’expliquer quand utiliser chacune, et te mettre en garde contre les pièges dans lesquels même les développeurs expérimentés tombent. C’est parti !
\n\nMéthode n°1 : insert() — le classique
\n\nLa méthode la plus évidente et la plus utilisée est la méthode insert(). Elle permet d’insérer tous les éléments d’un vecteur à la fin d’un autre. La syntaxe est simple et élégante :
#include <iostream>\n#include <vector>\n\nint main() {\n std::vector<int> vec1 = {1, 2, 3};\n std::vector<int> vec2 = {4, 5, 6};\n\n // Concaténation : on insère vec2 à la fin de vec1\n vec1.insert(vec1.end(), vec2.begin(), vec2.end());\n\n // Affichage : 1 2 3 4 5 6\n for (int v : vec1) std::cout << v << " ";\n return 0;\n}\n\nComment ça marche : On dit au compilateur : « À partir de la position vec1.end() (c’est-à-dire après le dernier élément du premier vecteur), copie tout ce qui se trouve entre vec2.begin() et vec2.end() ». Et voilà — la fusion de vecteurs C++ est effectuée.
Avantages et inconvénients de insert()
\n- \n
- ✅ Avantages : Simplicité, lisibilité, fonctionne avec tous les types. \n
- ❌ Inconvénients : Si
vec1est petit etvec2est énorme, plusieurs réallocations mémoire peuvent se produire lors de l’insertion. Cela réduit les performances lors de la concaténation de vecteurs de gros volumes. \n
Conseil : Si tu connais la taille finale, appelle vec1.reserve(vec1.size() + vec2.size()) à l’avance. Cela évitera les allocations inutiles.
Méthode n°2 : std::merge() — pour les données triées
\n\nEt si tes vecteurs sont déjà triés ? Ou si tu as besoin non seulement de concaténer, mais d’obtenir un tableau unique trié ? C’est là qu’intervient l’algorithme std::merge du fichier d’en-tête <algorithm>.
#include <iostream>\n#include <vector>\n#include <algorithm> // pour std::merge\n\nint main() {\n std::vector<int> vec1 = {1, 3, 5};\n std::vector<int> vec2 = {2, 4, 6};\n std::vector<int> result;\n\n // Réservons de l’espace pour éviter les copies inutiles\n result.reserve(vec1.size() + vec2.size());\n\n // Fusionnons les deux plages triées\n std::merge(vec1.begin(), vec1.end(),\n vec2.begin(), vec2.end(),\n std::back_inserter(result));\n\n // Affichage : 1 2 3 4 5 6\n for (int v : result) std::cout << v << " ";\n return 0;\n}\n\nNote bien : std::merge exige que les deux plages d’entrée soient triées par ordre croissant. Si ce n’est pas le cas, le résultat sera imprévisible. En revanche, si les données sont ordonnées, cette méthode est la reine des performances : complexité O(n + m).
Quand utiliser std::merge ?
\n- \n
- Si tu fusionnes les résultats de deux requêtes SQL ou de journaux triés par date. \n
- Quand tu as besoin non seulement d’un concatenating two std::vectors, mais d’une fusion triée. \n
- Si les vecteurs d’origine ne peuvent pas être modifiés (on crée un troisième vecteur
result). \n
Méthode n°3 : Sémantique de déplacement — la rapidité pour C++11 et plus
\n\nSupposons que tu n’aies plus besoin des vecteurs d’origine après