如何在没有副本的独特向量中传递小向量的集合

时间:2013-03-01 17:01:24

标签: c++ map stl

我有一个map<T,vector<double> >,说T=char vector<double>的值length<nn=5。我想将每个vector<double>从地图转移到一个长vector<double>的大n*mapsize,每个向量都插入索引5*k。如果可能的话,所有这些都不需要复制。

#include <vector>
#include <map>
using namespace std;
int main()
{
    typedef vector<double> Vec;
    typedef map<char, vector<double> >::iterator ItMap;

    //create a map<char,vector<double>> with 2 keys holding resp 2-3 elem vectors
    double v_value[] = {1.1,2.4};
    Vec v(v_value, v_value + sizeof(v_value)/sizeof(double));
    map<char,vector<double> > myMap;
    myMap['A'] = v;
    v.push_back(10);
    myMap['B'] = v;

    //create the vector that should get all the small vectors
    Vec receipt;
    receipt.reserve(10);

    for(ItMap it = myMap.begin(); it != myMap.end(); ++it) {
        it->second.resize(5);
        receipt.insert(receipt.end(),it->second.begin(),it->second.end());
    }
}

编辑:我使用我的解决方案进行了编辑,但它确实会复制。

2 个答案:

答案 0 :(得分:5)

正如我在评论中所解释的那样,没有复制就不可能;映射中的每个向量都是一个单独管理的动态数组,新向量是一个新的大数组。必须复制值。我不担心这个,除非你已经分析过,并且看到它是一个重要的问题。

本着这种精神,std::copy救援...... de de de de de dum de dum ...

#include <vector>
#include <map>
#include <algorithm>

template<typename T, size_t N>
size_t length(T (&)[N]) {
   return N;
}

int main()
{
    typedef std::vector<double> Vec;
    typedef std::map<char, vector<double> >::iterator ItMap;

    //create a map<char,vector<double>> with 2 keys holding resp 2-3 elem vectors
    double v_value[] = {1.1,2.4};
    Vec v(v_value, v_value + length(v_value));
    std::map<char,vector<double> > myMap;
    myMap['A'] = v;
    v.push_back(10);
    myMap['B'] = v;

    //create the vector that should get all the small vectors
    Vec receipt(10);

    for(ItMap it = myMap.begin(); it != myMap.end(); ++it) {
        std::copy(it->second.begin(), it->second.end(), std::back_inserter(receipt));
    }
}

对于用户定义的和/或比double更复杂的类型,如果您的目标编译器支持, 可以更有效地使用std::move C ++ 11

我已经演示了一个计算数组长度的小技巧......我总是对sizeof感到困惑。

PS我讨厌 using namespace std

答案 1 :(得分:1)

如果你的向量包含任何便宜的可移动和昂贵的复制,你可以使用std::move将每个小向量的内容移动到大向量中:

std::vector<T2> big_vector;
std::map<T1, std::vector<T2>> m = ....;

#include <algorithm> // for this std::move overload
#include <iterator>  // for std::back_inserter

for(auto& e : m) {
  std::move(m.second.begin(), m.second.end(), std::back_inserter(big_vector));
}

另一方面,由于您要存储doubles,因此除了复制之外,您无能为力。上面的方法可以使用,但是move用于复制。所以最后一个循环可以用

代替
for(const auto& e : m) {
  std::copy(m.second.begin(), m.second.end(), std::back_inserter(big_vector));
}