Qual é a melhor maneira de concatenar dois vetores?

Estou usando multitreading e quero mesclar os resultados. Por exemplo:

std::vector A; std::vector B; std::vector AB; 

Eu quero que a AB tenha o conteúdo de A e o conteúdo de B nessa ordem. Qual é a maneira mais eficiente de fazer algo assim?

 AB.reserve( A.size() + B.size() ); // preallocate memory AB.insert( AB.end(), A.begin(), A.end() ); AB.insert( AB.end(), B.begin(), B.end() ); 

Isto é precisamente o que a function de membro std::vector::insert é para

 std::vector AB = A; AB.insert(AB.end(), B.begin(), B.end()); 

Depende se você realmente precisa concatenar fisicamente os dois vetores ou se deseja dar a aparência de concatenação por causa da iteração. A function boost :: join

http://www.boost.org/doc/libs/1_43_0/libs/range/doc/html/range/reference/utilities/join.html

vai te dar isso.

 std::vector v0; v0.push_back(1); v0.push_back(2); v0.push_back(3); std::vector v1; v1.push_back(4); v1.push_back(5); v1.push_back(6); ... BOOST_FOREACH(const int & i, boost::join(v0, v1)){ cout << i << endl; } 

deveria te dar

 1 2 3 4 5 6 

Nota boost :: join não copia os dois vetores em um novo container, mas gera um par de iteradores (range) que cobrem o span de ambos os containers. Haverá alguma sobrecarga de desempenho, mas talvez menos que copiar todos os dados para um novo contêiner primeiro.

Com base na resposta de Kiril V. Lyadvinsky , fiz uma nova versão. Este modelo de uso de snippet e sobrecarga. Com ele, você pode escrever vector3 = vector1 + vector2 e vector4 += vector3 . Espero que possa ajudar.

 template  std::vector operator+(const std::vector &A, const std::vector &B) { std::vector AB; AB.reserve( A.size() + B.size() ); // preallocate memory AB.insert( AB.end(), A.begin(), A.end() ); // add A; AB.insert( AB.end(), B.begin(), B.end() ); // add B; return AB; } template  std::vector &operator+=(std::vector &A, const std::vector &B) { A.reserve( A.size() + B.size() ); // preallocate memory without erase original data A.insert( A.end(), B.begin(), B.end() ); // add B; return A; // here A could be named AB } 

mais uma variante simples que não foi mencionada:

 copy(A.begin(),A.end(),std::back_inserter(AB)); copy(B.begin(),B.end(),std::back_inserter(AB)); 

e usando o algoritmo de mesclagem:


#include #include #include #include #include #include template class Container, class T> std::string toString(const Container& v) { std::stringstream ss; std::copy(v.begin(), v.end(), std::ostream_iterator(ss, "")); return ss.str(); }; int main() { std::vector A(10); std::vector B(5); //zero filled std::vector AB(15); std::for_each(A.begin(), A.end(), [](int& f)->void { f = rand() % 100; }); std::cout << "before merge: " << toString(A) << "\n"; std::cout << "before merge: " << toString(B) << "\n"; merge(B.begin(),B.end(), begin(A), end(A), AB.begin(), [](int&,int&)->bool {}); std::cout << "after merge: " << toString(AB) << "\n"; return 1; }

Se seus vetores estão classificados *, confira set_union de .

 set_union(A.begin(), A.end(), B.begin(), B.end(), AB.begin()); 

Há um exemplo mais completo no link

* obrigado rlbond

Todas as soluções estão corretas, mas achei mais fácil apenas escrever uma function para implementar isso. como isso:

 template  void ContainerInsert(T1 t1, T2 t2) { t1->insert(t1->end(), t2->begin(), t2->end()); } 

Dessa forma, você pode evitar o posicionamento temporário assim:

 ContainerInsert(vec, GetSomeVector());