我正在使用多步操作,并希望合并结果。例如:
std::vector<int> A;
std::vector<int> B;
std::vector<int> AB;
我想让AB有A的内容和B的内容按照这个顺序。做这样的事情最有效的方法是什么?
我正在使用多步操作,并希望合并结果。例如:
std::vector<int> A;
std::vector<int> B;
std::vector<int> AB;
我想让AB有A的内容和B的内容按照这个顺序。做这样的事情最有效的方法是什么?
当前回答
基于Kiril V. Lyadvinsky的回答,我做了一个新的版本。这个片段使用模板和重载。有了它,你可以写vector3 = vector1 + vector2和vector4 += vector3。希望能有所帮助。
template <typename T>
std::vector<T> operator+(const std::vector<T> &A, const std::vector<T> &B)
{
std::vector<T> 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 <typename T>
std::vector<T> &operator+=(std::vector<T> &A, const std::vector<T> &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
}
其他回答
如果你的向量排序*,检查set_union从<algorithm>。
set_union(A.begin(), A.end(), B.begin(), B.end(), AB.begin());
链接中有一个更详细的例子。
对于这个用例,如果您预先知道每个线程产生的结果的数量,那么您可以预先分配AB并将std::span传递给每个线程。这样就不需要进行连接。例子:
std::vector<int> AB(total_number_of_results, 0);
std::size_t chunk_length = …;
std::size_t chunk2_start = chunk_length;
std::size_t chunk3_start = 2 * chunk_length; // If needed
…
// Pass these to the worker threads.
std::span<int> A(AB.data(), chunk_length);
std::span<int> B(AB.data() + chunk2_start, chunk_length);
…
还有一个没有提到的简单变体:
copy(A.begin(),A.end(),std::back_inserter(AB));
copy(B.begin(),B.end(),std::back_inserter(AB));
并使用合并算法:
#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
#include <sstream>
#include <string>
template<template<typename, typename...> class Container, class T>
std::string toString(const Container<T>& v)
{
std::stringstream ss;
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(ss, ""));
return ss.str();
};
int main()
{
std::vector<int> A(10);
std::vector<int> B(5); //zero filled
std::vector<int> 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;
}
这正是成员函数std::vector::insert的作用
std::vector<int> AB = A;
AB.insert(AB.end(), B.begin(), B.end());
AB.reserve( A.size() + B.size() ); // preallocate memory
AB.insert( AB.end(), A.begin(), A.end() );
AB.insert( AB.end(), B.begin(), B.end() );