[英]Convert vector<std::string> to vector<double>
我有一个字符串向量,如{"1.2","3.4","0.5","200.7"}
。
我想将每个元素转换为double并将其存储在vector<double>
。
像这样{1.2,3.4,0.5,200.7}
最好的方法是什么?
我知道std::stod(string, size)
; 但我希望有更好的方法来做到这一点。
我在寻找类似的东西:
vector<double> doubleVector = convertStringVectortoDoubleVector(myStringVector);
似乎没有那样的东西; 那么下一个最好的东西是什么?
编辑:这是我最终使用的:
std::vector<double> convertStringVectortoDoubleVector(const std::vector<std::string>& stringVector){
std::vector<double> doubleVector(stringVector.size());
std::transform(stringVector.begin(), stringVector.end(), doubleVector.begin(), [](const std::string& val)
{
return stod(val);
});
return doubleVector;}
如需完整答案,请查看zac howland的回答和Chris Jester-Young的回答。 (PS这完全基于Zac的答案)谢谢
为了完整性(因为Chris从他的回答中删除了编辑):
std::vector<double> doubleVector(stringVector.size());
std::transform(stringVector.begin(), stringVector.end(), doubleVector.begin(), [](const std::string& val)
{
return std::stod(val);
});
与没有reserve
std::back_inserter
比较
没有保留,每次back_inserter
调用push_back
都会冒着重新调整数组大小的风险。 它必须根据当前容量检查当前大小,如果需要增加容量,它会将向量复制到新位置(容量增加)。 毕竟,它将增加大小并插入新元素。 当你知道开始时的大小(它将匹配stringVector
的大小)时,这是一个很大的开销。
比较使用std::back_inserter
和reserve
保留适当的内存量将阻止重新分配问题,但push_back
仍会更新大小并检查每次迭代是否已达到容量。 你已经减少了很多开销(由于调整大小问题,不再需要“移动”数组),但你仍然有很多不需要的条件检查。
最初设置大小的开销很小,将所有元素设置为默认值(在双精度的情况下为0.0)。 每次迭代,您只需设置当前元素的值即可。 因此,对于N个元素的向量,您有2N + 2个赋值(设置容量,大小,元素的初始值和元素的实际值),没有不需要的条件检查。 除了N个条件检查之外,保留方法还有2N + 1个赋值(设置容量一次,更新大小N次,并设置N个双精度值)。
如果你真的想进一步优化它,你可以创建自己的迭代器包装器进行转换,这样你就可以在初始化向量时为双打写正确的值:
// pseudo-code
std::vector<double> doubleVector(my_string_conversion_iterator(stringVector.begin()), my_string_conversion_iterator(stringVector.end());
您应该使用std::transform
将转换应用于每个元素。
vector<double> doubleVector;
doubleVector.reserve(stringVector.size());
transform(stringVector.begin(), stringVector.end(), back_inserter(doubleVector),
[](string const& val) {return stod(val);});
正如Zac Howland所指出的,这是另一种方法,它首先使用默认构造的元素初始化向量,然后简单地用正确的值填充向量:
vector<double> doubleVector(stringVector.size());
transform(stringVector.begin(), stringVector.end(), doubleVector.begin(),
[](string const& val) {return stod(val);});
这种方法的优点是矢量的大小恰好一次,而不是连续增长。 缺点是向量元素必须首先默认构造,然后用正确的值重新分配。 对于满足以下所有条件的元素类型,这种权衡是值得的:
在这种情况下, double
满足所有四个要求,因此后一种方法更好。 对于其他类型,特别是在编写函数模板时,您的默认实现应使用前一种方法。
使用std::transform
vector<string> str ;
vector<double> dv ;
std::transform(str.begin(), str.end(), back_inserter(dv), [](const string & astr){ return stod( astr) ; } ) ;
你可以在C ++ 11中使用std:for_each
和lambda
。
vector<string> a = {"1.2","3.4","0.5","200.7"};
vector<double> b;
for_each(a.begin(), a.end(), [&b](const string &ele) { b.push_back(stod(ele)); });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.