0

我有一个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());
    }
}

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

4

2 回答 2

5

正如我在评论中解释的那样,不复制是不可能的;地图中的每个向量都是一个单独管理的动态数组,新向量是一个新的大数组。必须复制这些值。我不会担心这一点,除非您已经分析并看到这是一个重要问题。

本着这种精神,std::copy为了救援...... 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));
    }
}

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

我演示了一个计算数组长度的小技巧……我总是对sizeof.

PS我讨厌 using namespace std

于 2013-03-01T17:07:16.867 回答
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));
}
于 2013-03-01T17:04:34.730 回答