如何连接多个std::vectors?
How to concatenate many std::vectors?
已经有一个关于如何连接两个向量的问题:Concatenating two std::vectors。但是,我发现开始一个新问题是合适的,因为我的问题更具体一些....
我有两个 类 看起来像这样:
class AClass {
public:
std::vector<double> getCoeffs() {return coeffs;}
private:
std::vector<double> coeffs;
};
class BClass {
public:
std::vector<double> getCoeffs() {return ...;}
private:
std::vector<AClass> aVector;
};
连接 aVector 中每个元素的系数的最佳方法是什么(即避免不必要的复制等)?
我的第一次尝试是
std::vector<double> BClass::getCoeffs(){
std::vector<double> coeffs;
std::vector<double> fcoefs;
for (int i=0;i<aVector.size();i++){
fcoefs = aVector[i].getCoeffs();
for (int j=0;j<fcoefs.size();j++{
coeffs.push_back(fcoefs[j]);
}
}
return coeffs;
}
我已经知道如何避免内部 for 循环(多亏了上面提到的 post),但我很确定,在一些标准算法的帮助下,这可以在一行中完成.
我目前无法使用 C++11。尽管如此,我也对如何在 C++11 中做到这一点感兴趣(如果比 "no C++11" 有任何优势)。
编辑:我会试着稍微改一下问题,让它更清楚。
连接两个向量可以通过插入来完成。对于我的例子,我会使用这个:
std::vector<double> BClass::getCoeffs(){
std::vector<double> coeffs;
std::vector<double> fcoefs;
for (int i=0;i<aVector.size();i++){
fcoefs = aVector[i].getCoeffs();
coeffs.insert(coeffs.end(),fcoefs.begin(),fcoefs.end());
}
return coeffs;
}
是否可以避免for循环?
我可以想象可以写出类似
的东西
for_each(aVector.begin(),aVector.end(),coeffs.insert(coeffs.end(),....);
您可以在 C++11 中执行此操作:
std::for_each(aVector.begin(), aVector.end(), [&](AClass i){const auto& temp = i.getCoeffs(); coeffs.insert(coeffs.end(), temp.begin(), temp.end());});
C++03 更难,因为它缺少 lambda 和 bind
.
你能做的就是在你的内部循环中使用复制:
for(std::vector<AClass>::iterator it = aVector.begin(); it != aVector.end(); ++it){
const std::vector<double>& temp = it->getCoeffs();
coeffs.insert(coeffs.end(), temp.begin(), temp.end());
}
它们本质上是同一件事,尽管您可以通过从 getCoeffs
.
返回 const std::vector<double>&
来改进两者的运行时间
编辑:
Arg,刚刚看到您在问题中添加了 insert
。我以为我真的会在那里帮助你。作为一个安慰提示,您在这里真正要问的是压平 std::vectors
的 std::vector
。有答案here. But should you have access to boost you should look at: http://www.boost.org/doc/libs/1_57_0/libs/multi_array/doc/reference.html#synopsis
第一步是避免额外分配。如果您知道您不会增加 return 值,您可以预留到恰好合适的大小。
std::vector<double> BClass::getCoeffs(){
typedef std::vector<double> dvec;
dvec coeffs;
typedef std::vector<AClass> avec;
typedef std::vector<dvec> ddvec;
ddvec swap_space;
swap_space.reserve(aVector.size());
size_t capacity = 0;
for (avec::const_iterator it = aVector.begin(); it != aVector.end(); ++it) {
dvec v = it->getCoeffs(); // RVO elision!
capacity += v.size();
swap_space.push_back();
v.swap(swap_space.back());
}
dvec retval;
retval.reserve(capacity);
for (ddvec::iterator it = swap_space.begin(); it != swap_space.end(); ++it) {
retval.insert( retval.end(), it->begin(), it->end() );
}
return retval; // NRVO
}
这应该避免对每个 AClass 进行多次分配(由它们的 API 强制执行!您应该有一个 vector<?> const&
访问器),加上 return 值的一次分配。
建议修复 AClass
。
已经有一个关于如何连接两个向量的问题:Concatenating two std::vectors。但是,我发现开始一个新问题是合适的,因为我的问题更具体一些....
我有两个 类 看起来像这样:
class AClass {
public:
std::vector<double> getCoeffs() {return coeffs;}
private:
std::vector<double> coeffs;
};
class BClass {
public:
std::vector<double> getCoeffs() {return ...;}
private:
std::vector<AClass> aVector;
};
连接 aVector 中每个元素的系数的最佳方法是什么(即避免不必要的复制等)?
我的第一次尝试是
std::vector<double> BClass::getCoeffs(){
std::vector<double> coeffs;
std::vector<double> fcoefs;
for (int i=0;i<aVector.size();i++){
fcoefs = aVector[i].getCoeffs();
for (int j=0;j<fcoefs.size();j++{
coeffs.push_back(fcoefs[j]);
}
}
return coeffs;
}
我已经知道如何避免内部 for 循环(多亏了上面提到的 post),但我很确定,在一些标准算法的帮助下,这可以在一行中完成.
我目前无法使用 C++11。尽管如此,我也对如何在 C++11 中做到这一点感兴趣(如果比 "no C++11" 有任何优势)。
编辑:我会试着稍微改一下问题,让它更清楚。 连接两个向量可以通过插入来完成。对于我的例子,我会使用这个:
std::vector<double> BClass::getCoeffs(){
std::vector<double> coeffs;
std::vector<double> fcoefs;
for (int i=0;i<aVector.size();i++){
fcoefs = aVector[i].getCoeffs();
coeffs.insert(coeffs.end(),fcoefs.begin(),fcoefs.end());
}
return coeffs;
}
是否可以避免for循环? 我可以想象可以写出类似
的东西for_each(aVector.begin(),aVector.end(),coeffs.insert(coeffs.end(),....);
您可以在 C++11 中执行此操作:
std::for_each(aVector.begin(), aVector.end(), [&](AClass i){const auto& temp = i.getCoeffs(); coeffs.insert(coeffs.end(), temp.begin(), temp.end());});
C++03 更难,因为它缺少 lambda 和 bind
.
你能做的就是在你的内部循环中使用复制:
for(std::vector<AClass>::iterator it = aVector.begin(); it != aVector.end(); ++it){
const std::vector<double>& temp = it->getCoeffs();
coeffs.insert(coeffs.end(), temp.begin(), temp.end());
}
它们本质上是同一件事,尽管您可以通过从 getCoeffs
.
const std::vector<double>&
来改进两者的运行时间
编辑:
Arg,刚刚看到您在问题中添加了 insert
。我以为我真的会在那里帮助你。作为一个安慰提示,您在这里真正要问的是压平 std::vectors
的 std::vector
。有答案here. But should you have access to boost you should look at: http://www.boost.org/doc/libs/1_57_0/libs/multi_array/doc/reference.html#synopsis
第一步是避免额外分配。如果您知道您不会增加 return 值,您可以预留到恰好合适的大小。
std::vector<double> BClass::getCoeffs(){
typedef std::vector<double> dvec;
dvec coeffs;
typedef std::vector<AClass> avec;
typedef std::vector<dvec> ddvec;
ddvec swap_space;
swap_space.reserve(aVector.size());
size_t capacity = 0;
for (avec::const_iterator it = aVector.begin(); it != aVector.end(); ++it) {
dvec v = it->getCoeffs(); // RVO elision!
capacity += v.size();
swap_space.push_back();
v.swap(swap_space.back());
}
dvec retval;
retval.reserve(capacity);
for (ddvec::iterator it = swap_space.begin(); it != swap_space.end(); ++it) {
retval.insert( retval.end(), it->begin(), it->end() );
}
return retval; // NRVO
}
这应该避免对每个 AClass 进行多次分配(由它们的 API 强制执行!您应该有一个 vector<?> const&
访问器),加上 return 值的一次分配。
建议修复 AClass
。