转换向量< std :: string>到向量< double> [英] Convert vector<std::string> to vector<double>

查看:340
本文介绍了转换向量< std :: string>到向量< double>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字符串向量,如 {1.2,3.4,0.5,200.7}



我想将每个元素转换为双精度值并将其存储在向量< double>



像这样 {1.2,3.4,0.5,200.7}



这将是最好的方法?



我知道 std :: stod(string,size) ;



我在寻找类似的东西:

  vector< double> doubleVector = convertStringVectortoDoubleVector(myStringVector); 

似乎没有什么像这样的;那么下一个最好的东西是什么?






编辑:
感谢所有的答案为懒惰)。
所以对于像我这样的惰性人来说,这里是convertStringVectortoDoubleVector函数:

  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-杨的答案。
(PS这完全基于Zac的回答)
感谢

解决方案

从他的答案编辑):

  std :: vector< double& doubleVector(stringVector.size()); 
std :: transform(stringVector.begin(),stringVector.end(),doubleVector.begin(),[](const std :: string& val)
{
return std: :stod(val);
});

比较使用 std :: back_inserter 没有保留



没有保留,你有风险必须调整数组的大小时间 back_inserter 调用 push_back 。它必须根据当前容量检查当前大小,并且如果容量需要增加,则它将向量复制到新位置(具有增加的容量)。毕竟,它将增加大小并插入新的元素。这是很大的开销,当你知道什么大小应该开始(它将匹配 stringVector 的大小)。



使用保留 比较使用 std :: back_inserter p>

保留适当的内存量将防止重新分配问题,但 push_back 仍会更新大小,并进行检查如果容量已经达到每次迭代。你已经减少了很多开销(不再运行的风险,移动数组,因为大小问题),但你仍然有很多不必要的条件检查。



初始设置大小需要将所有元素设置为默认值(在双精度的情况下为0.0)。每次迭代,你只需要设置当前元素的值。因此,对于N个元素的向量,您有2N + 2个赋值(设置容量,大小,元素的初始值和元素的实际值),而不需要进行不必要的条件检查。除了N个条件检查之外,保留方法具有2N + 1个分配(设置容量一次,更新大小N次,并设置N个双精度值)。



如果你真的想进一步优化它,你可以创建自己的迭代器包装器做转换,这将允许你在初始化向量时为双精度值写入正确的值:

  //伪代码
std :: vector< double> doubleVector(my_string_conversion_iterator(stringVector.begin()),my_string_conversion_iterator(stringVector.end());


I have a string vector like {"1.2","3.4","0.5","200.7"}.

I would like to convert each element into double and store it in a vector<double>.

Like so {1.2,3.4,0.5,200.7}

What would be the best way to do this?

I know of the std::stod(string, size); But I am hoping for a better way to do this.

I was looking for something like:

vector<double> doubleVector = convertStringVectortoDoubleVector(myStringVector);

There doesn't seem to be anything like that; so what is the next best thing?


EDIT: Thanks for all the answers (and all the criticism for being lazy). So for lazy people like me here's the convertStringVectortoDoubleVector function:

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;}

For a complete answer check out zac howland's answer and Chris Jester-Young's answer. (P.S. This is based entirely on Zac's answer) Thanks

解决方案

For completeness (since Chris removed the edit from his answer):

std::vector<double> doubleVector(stringVector.size());
std::transform(stringVector.begin(), stringVector.end(), doubleVector.begin(), [](const std::string& val)
{
    return std::stod(val);
});

Comparison to using std::back_inserter without reserve

Without reserve, you run the risk of having to resize the array each time the back_inserter calls push_back. It has to check the current size against the current capacity, and if the capacity needs to be increased, it will copy the vector to a new location (with increased capacity). After all of that, it will increase the size and insert the new element. This is a lot of overhead when you know what the size should be to start with (it will match the size of the stringVector).

Comparision to using std::back_inserter with reserve

Reserving the proper amount of memory will prevent the reallocation problem, but push_back still updates the size and does the check to see if the capacity has been reached each iteration. You've reduced the overhead a lot (no longer running the risk of having to "move" the array because of sizing issues), but you still have a lot of unneeded conditional checks.

Setting the size initially has a small overhead of setting all the elements to a default value (0.0 in the case of doubles). With each iteration, you are then simply setting the value of the current element. So for a vector of N elements, you have 2N + 2 assignments (setting the capacity, size, the initial value of the elements, and the real value of the elements) with no unneeded conditional checks. The reserve method has 2N + 1 assignments (set the capacity once, update the size N times, and set the value of N doubles) in addition to N conditional checks.

If you really wanted to optimize it even further, you could create your own iterator wrapper that does the conversion, which would then allow you to write the correct value for the doubles when you initialize the vector:

// pseudo-code
std::vector<double> doubleVector(my_string_conversion_iterator(stringVector.begin()), my_string_conversion_iterator(stringVector.end());

这篇关于转换向量&lt; std :: string&gt;到向量&lt; double&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆