从向量的向量填充向量的有效方法是啥?

Posted

技术标签:

【中文标题】从向量的向量填充向量的有效方法是啥?【英文标题】:What is the efficient way to populate vector from vector of vector?从向量的向量填充向量的有效方法是什么? 【发布时间】:2014-03-21 14:08:42 【问题描述】:

我有一个像std::vector< std::vector< int> > 这样的向量向量,我想从这个向量中填充std::vector< int>,你能告诉我有效的方法吗?可能有一些我可以使用的增强功能。我正在使用VS2010。下面的代码 sn-p 是我尝试过的:

std::vector<std::vector<int> >::iterator outereItr = vecOfVec.begin();

while(outereItr != vecOfVec.end()) 

    std::vector<int>::iterator innerItr1 = (*outereItr).begin();
    while(innerItr1 != (*outereItr).end())
    
        masterVec.push_back(*innerItr1);
        ++innerItr1;
    
    ++outereItr;

【问题讨论】:

您的意思是遍历向量向量的所有子向量并仅用它们的内容填充一个向量吗? 老哥,听说你喜欢矢量... 【参考方案1】:

您可以使用insert 插入整个向量,而不是单独插入每个元素。这可能会减少重新分配的次数。

for (auto const & vec : vecOfVec) 
    masterVec.insert(masterVec.end(), vec.begin(), vec.end());

或者,如果您的编译器不支持新式 for 循环和类型推导

for (std::vector<std::vector<int> >::iterator it = vecOfVec.begin(); it != vecOfVec.end(); ++it) 
    masterVec.insert(masterVec.end(), it->begin(), it->end());

将所有向量的大小相加可能会(也可能不会)更有效,然后在开始之前在masterVec 中保留足够的空间。

【讨论】:

VS2010不能为每个人做。 @Danvil:好的,我已经添加了令人讨厌的旧方法。 几乎可以肯定的是,预先确定尺寸会更好:尺寸将彼此本地化。 谢谢大家。我将修改我的代码以使用 insert()。另外,我可以使用 BOOST_FOREACH 来代替 for 循环来避免如此长的迭代器声明。是的,先计算大小然后插入是个好主意。 BOOST_FOREACH(std::vector&lt;int&gt;&amp; vec, vecOfVec) masterVec.insert(masterVec.end(), vec.begin(), vec.end()); 【参考方案2】:

您可以使用函数std::vector::insert。

std::vector<int> masterVec;
for(std::vector<std::vector<int> >::iterator it=vecOfVec.begin(); it!=vecOfVec.end(); ++it) 
    masterVec.insert(masterVec.end(), it->begin(), it->end());

如果你可以使用 C++11,代码会更简洁:

std::vector<int> masterVec;
for(const auto& x : vecOfVec) 
    masterVec.insert(masterVec.end(), x.begin(), x.end());

正如 Kiril 在 cmets 中指出的那样,首先计算结果向量的大小是避免重新分配的好主意:

size_t size = 0;
for(std::vector<std::vector<int> >::iterator it=vecOfVec.begin(); it!=vecOfVec.end(); ++it) 
    size += it->size();

std::vector<int> masterVec;
masterVec.reserve(size);
for(std::vector<std::vector<int> >::iterator it=vecOfVec.begin(); it!=vecOfVec.end(); ++it) 
    masterVec.insert(masterVec.end(), it->begin(), it->end());

【讨论】:

感谢上帝现在的汽车。 我会再添加一个for-loop 来提前计算大小,然后使用std::vector::reserve。是的,这增加了一个循环,但几乎 100% 肯定,它会更快,因为重新分配真的,真的很慢(特别是如果有很多数据,甚至更多,如果 @ 987654327@ 被替换为更大的类型(更不用说自定义定义的重类)。 那是一个错字。修好了。

以上是关于从向量的向量填充向量的有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从长(且合理)稀疏向量中选择随机元素的最有效方法是啥?

从向量中删除项目

C++ 将大量向量转换为字符向量的最有效方法

为满足条件的特定 int 搜索向量的有效方法?

在winsock中重用向量作为数组的更有效方法?

C/C++:使用函数返回的向量的有效方法