我有一个向量的向量,我想把它的内容放到一个列向量中。即,
输入:A = [[1 2] [3 4]]
输出:v = [[1] [2] [3] [4]](列向量)
有没有一种快速的方法在C ++中这样做?
不幸的是,我必须告诉你,至少到目前为止,其他所有答案都不如看起来那么好。
让我们一步一步解答;最后我告诉你如何正确处理它。
std::vector<std::vector<int>> v = {{1, 2, 3}, {2, 2, 3}};
std::vector<int> b;
for(auto& vec : v){
std::copy(vec.begin(), vec.end(), std::back_inserter(b)); // performes single insertion at the end
}
std::copy
是插入std::vector
的坏风格。您可以在目标向量的末尾按值插入值。这意味着可能需要更多的重新分配和移动/复制。
std::vector<std::vector<int>> vv = { { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
std::vector<int> v;
for (auto row : vv) {
for (auto el : row) {
v.push_back(el);
}
}
同样在这里。你在每个push_back
调整大小,这绝对没有必要!
我建议你使用std::vector::insert
。它自己执行一些内部调整。
std::vector<std::vector<int>> v = {{1, 2, 3}, {2, 2, 3}};
std::vector<int> b;
for(auto& vec : v){
b.insert(std::cend(b), std::cbegin(vec), std::cend(vec));
}
此解决方案在发生任何插入之前执行调整大小。这将带来最佳性能。
这里有一些测试代码。亲自尝试:
#include <vector>
#include <chrono>
#include <iostream>
int main()
{
std::vector<int> v(100'000'000, 5);
auto start = std::chrono::steady_clock::now();
std::vector<int> b;
b.insert(std::cend(b), std::cbegin(v), std::cend(v));
auto end = std::chrono::steady_clock::now();
std::cout << "insert durtion:\t" << (end - start).count() << std::endl;
b = std::vector<int>();
start = std::chrono::steady_clock::now();
std::copy(std::cbegin(v), std::cend(v), std::back_inserter(b));
end = std::chrono::steady_clock::now();
std::cout << "copy durtion:\t" << (end - start).count() << std::endl;
b = std::vector<int>();
start = std::chrono::steady_clock::now();
for (auto el : v)
b.push_back(el);
end = std::chrono::steady_clock::now();
std::cout << "copy durtion:\t" << (end - start).count() << std::endl;
std::cin.ignore();
return 0;
}
这将在此输出中生成x64版本:
insert durtion: 132388657
copy durtion: 844505239
push_back durtion: 866565409
最后,你当然可以首先resize
矢量然后开始复制,但我认为这是处理它的错误方法,如果事实上,std::vector
已经为我们提供了这个解决方案。
像这样:
std::vector<std::vector<int>> a = {{1, 2}, {3, 4}};
std::vector<std::vector<int>> b;
for ( auto& row : a )
{
for ( auto item: row )
{
b.push_back(std::vector<int>{item});
}
}
你可以使用std::copy
每行std::back_inserter
像这样:
int main()
{
std::vector<std::vector<int>> v = {{1, 2, 3}, {2, 2, 3}};
std::vector<int> b;
for(auto& vec : v){
std::copy(vec.begin(), vec.end(), std::back_inserter(b));
}
}
如果要将向量矢量中的所有元素复制到单个向量中,请使用两个循环:
std::vector<std::vector<int>> vv = { { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
std::vector<int> v;
for (auto row : vv) {
for (auto el : row) {
v.push_back(el);
}
}
//print out the vector:
for (auto el : v) {
std::cout << el << ' ';
}
或利用std::copy功能。