Rob*_*ble 668
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
Run Code Online (Sandbox Code Playgroud)
小智 169
如果您正在使用C++ 11,并希望移动元素而不是仅复制它们,则可以std::move_iterator与insert(或copy)一起使用:
#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;
}
Run Code Online (Sandbox Code Playgroud)
对于带有整数的示例,这不会更有效,因为移动它们并不比复制它们更有效,但对于具有优化移动的数据结构,它可以避免复制不必要的状态:
#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;
}
Run Code Online (Sandbox Code Playgroud)
移动后,src的元素保留在未定义但安全的构造状态,并且其前面的元素最后直接转移到dest的新元素.
Tom*_*ter 132
我会使用insert函数,如:
vector<int> a, b;
//fill with data
b.insert(b.end(), a.begin(), a.end());
Run Code Online (Sandbox Code Playgroud)
Rog*_*mbe 74
或者您可以使用:
std::copy(source.begin(), source.end(), std::back_inserter(destination));
Run Code Online (Sandbox Code Playgroud)
如果两个向量不包含完全相同类型的东西,则此模式很有用,因为您可以使用某些东西而不是std :: back_inserter将一种类型转换为另一种类型.
Deq*_*ing 53
使用C++ 11,我更喜欢将vector附加到a:
std::move(b.begin(), b.end(), std::back_inserter(a));
Run Code Online (Sandbox Code Playgroud)
何时a和b不重叠,b不再使用.
这是std::move来自<algorithm>,而不是通常 std::move的<utility>.
Jam*_*ran 33
std::vector<int> first;
std::vector<int> second;
first.insert(first.end(), second.begin(), second.end());
Run Code Online (Sandbox Code Playgroud)
ST3*_*ST3 22
我更喜欢已经提到的一个:
a.insert(a.end(), b.begin(), b.end());
Run Code Online (Sandbox Code Playgroud)
但是如果你使用C++ 11,还有一种更通用的方法:
a.insert(std::end(a), std::begin(b), std::end(b));
Run Code Online (Sandbox Code Playgroud)
此外,不是问题的一部分,但建议reserve在追加更好的性能之前使用.如果你将向量与自身连接起来,没有保留它就会失败,所以你总是应该这样做reserve.
基本上你需要的是:
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());
}
Run Code Online (Sandbox Code Playgroud)
Vik*_*Roy 18
连接的一般性能提升是检查向量的大小。并将较小的与较大的合并/插入。
//vector<int> v1,v2;
if(v1.size()>v2.size()) {
v1.insert(v1.end(),v2.begin(),v2.end());
} else {
v2.insert(v2.end(),v1.begin(),v1.end());
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ger 13
如果您希望能够简洁地连接向量,您可以重载+=运算符。
template <typename T>
std::vector<T>& operator +=(std::vector<T>& vector1, const std::vector<T>& vector2) {
vector1.insert(vector1.end(), vector2.begin(), vector2.end());
return vector1;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样称呼它:
vector1 += vector2;
Run Code Online (Sandbox Code Playgroud)
小智 12
你应该使用vector :: insert
v1.insert(v1.end(), v2.begin(), v2.end());
Run Code Online (Sandbox Code Playgroud)
Jar*_*d42 11
使用范围v3,您可能会有一个懒惰的连接:
ranges::view::concat(v1, v2)
Run Code Online (Sandbox Code Playgroud)
演示.
Olp*_*pah 10
使用 C++20,您可以摆脱带有范围的 begin() 和 end()。
#include <ranges>
std::ranges::copy(vec2, std::back_inserter(vec1));
Run Code Online (Sandbox Code Playgroud)
或者如果你想移动元素:
std::ranges::move(vec2, std::back_inserter(vec1));
Run Code Online (Sandbox Code Playgroud)
如果您对强异常保证感兴趣(当复制构造函数可以抛出异常时):
template<typename T>
inline void append_copy(std::vector<T>& v1, const std::vector<T>& v2)
{
const auto orig_v1_size = v1.size();
v1.reserve(orig_v1_size + v2.size());
try
{
v1.insert(v1.end(), v2.begin(), v2.end());
}
catch(...)
{
v1.erase(v1.begin() + orig_v1_size, v1.end());
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
append_move如果向量元素的移动构造函数可以抛出(这不太可能,但仍然存在),则与强保证类似,一般无法实现。
有一个std::merge来自C++17的算法,在对输入向量进行排序时非常容易使用,
下面是示例:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
//DATA
std::vector<int> v1{2,4,6,8};
std::vector<int> v2{12,14,16,18};
//MERGE
std::vector<int> dst;
std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));
//PRINT
for(auto item:dst)
std::cout<<item<<" ";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在 C++23 中,可以使用其成员函数append_range(如果存在)将范围连接到标准容器。
因此,两个对象的串联std::vector可以通过以下方式执行:
vec1.append_range(vec2);
Run Code Online (Sandbox Code Playgroud)
将此添加到您的头文件中:
template <typename T> vector<T> concat(vector<T> &a, vector<T> &b) {
vector<T> ret = vector<T>();
copy(a.begin(), a.end(), back_inserter(ret));
copy(b.begin(), b.end(), back_inserter(ret));
return ret;
}
Run Code Online (Sandbox Code Playgroud)
并以这种方式使用它:
vector<int> a = vector<int>();
vector<int> b = vector<int>();
a.push_back(1);
a.push_back(2);
b.push_back(62);
vector<int> r = concat(a, b);
Run Code Online (Sandbox Code Playgroud)
r 将包含 [1,2,62]
如果您的目标只是为了只读目的而遍历值的范围,另一种方法是将两个向量都包裹在代理 (O(1)) 周围,而不是复制它们 (O(n)),以便立即看到它们作为一个单一的,连续的。
std::vector<int> A{ 1, 2, 3, 4, 5};
std::vector<int> B{ 10, 20, 30 };
VecProxy<int> AB(A, B); // ----> O(1)!
for (size_t i = 0; i < AB.size(); i++)
std::cout << AB[i] << " "; // ----> 1 2 3 4 5 10 20 30
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,包括“VecProxy”实现以及优缺点,请参阅/sf/answers/3908713091/。