【问题标题】:Convert vector<double> to vector<string> ( elegant way )将 vector<double> 转换为 vector<string> (优雅的方式)
【发布时间】:2014-10-11 20:56:00
【问题描述】:

我想知道是否有一种优雅的方式或内置函数将vector&lt;double&gt; 转换为vector&lt;string&gt;。我做的很简单

#include <iostream>
#include <string>
#include <vector>
#include <sstream>


std::vector<std::string> doubeVecToStr(const std::vector<double>& vec)
{
    std::vector<std::string> tempStr;

    for (unsigned int i(0); i < vec.size(); ++i){
        std::ostringstream doubleStr;
        doubleStr << vec[i];    
        tempStr.push_back(doubleStr.str());
    }

    return tempStr;
}


int main( int argc, char* argv[] )
{
    std::vector<double> doubleVec;
    doubleVec.push_back(1.0);
    doubleVec.push_back(2.1);
    doubleVec.push_back(3.2);

    std::vector<std::string> doubleStr;
    doubleStr = doubeVecToStr(doubleVec);

    for (unsigned int i(0); i < doubleStr.size(); ++i)
        std::cout << doubleStr[i] << "  ";

    std::cout << std::endl;

    return 0;
}

【问题讨论】:

  • 如果你不介意使用 Boost,你可以使用这个:boost.org/doc/libs/1_56_0/doc/html/string_algo/…
  • -1 这个问题不是关于(甚至没有提到)OP 后来claims 是他的目标以及问题的真正意义。
  • 为什么需要一个字符串向量?为什么不在需要时转换浮点数?
  • @Cheersandhth.-Alf,很抱歉,但这绝对是巧合。我确实考虑过适合这个问题的另一个答案。再次抱歉。

标签: c++ string vector double


【解决方案1】:

有很多方法,但标准解决方案是使用 std::transform 和 lambda,使用 std::to_string 进行转换:

std::transform(std::begin(doubleVec),
               std::end(doubleVec), 
               std::back_inserter(doubleStr),
               [](double d) { return std::to_string(d); } 
              );

您可以将其包装在一个函数模板中,使其适用于任何符合标准的容器:

template<class IteratorIn, class IteratorOut>
void to_string(IteratorIn first, IteratorIn last, IteratorOut out)
{
    std::transform(first, last, out,
                   [](typename std::iterator_traits<IteratorIn>::value_type d) { return std::to_string(d); } );
}

或者在 C++14 中,使用通用 lambda:

template<class IteratorIn, class IteratorOut>
void to_string(IteratorIn first, IteratorIn last, IteratorOut out)
{
    std::transform(first, last, out, [](auto d) { return std::to_string(d); } );
}

并使用任何容器调用它(例如,它适用于 std::list&lt;int&gt;):

to_string(std::begin(doubleVec), std::end(doubleVec), std::back_inserter(doubleStr));

注意事项:

  • 如果您没有 C++11 编译器,请编写自己的 to_string 函数模板:

例子:

template<class T>
std::string my_to_string(T v)
{
    std::stringstream ss;
    ss << v;
    return ss.str();
}

并以类似的方式使用它:

std::transform(doubleVec.begin(),
               doubleVec.end(),
               std::back_inserter(doubleStr), 
               my_to_string<double> );
  • 您应该reserve() 输出向量中的内存以避免在std::transform() 期间重新分配:

例如这样做:

std::vector<std::string> stringVec;
stringVec.reserve(v.size());   // reserve space for v.size() elements

Live demo

【讨论】:

  • std::begin(doubleVec), std::end(doubleVec)?
  • 这里不需要 lambda。
  • 或者可能有,因为它是重载的函数,否则需要一个丑陋的演员表。
  • @Neil 是的! (即使没有,它也会向 OP 展示如何在需要时调用它自己的转换函数)
  • 另外,它确保调用可以被内联并且不会通过函数指针。
【解决方案2】:

使用copyostream_iterator

#include <vector>
#include <iostream>
#include <sstream>
#include <iterator>

int main()
{
  std::vector<double> numbers{1.0, 2.1, 3.2};
  std::stringstream output;
  std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<double>(output, " "));

  std::cout << output.str() << std::endl;
}

【讨论】:

  • 不输出字符串向量。
  • @NeilKirk:好点。虽然,OP 无论如何都会将向量转换为字符串。如果这不是他想要的,我会删除这个答案。
【解决方案3】:

一般来说,如果你有一个T 的容器,并且想从T 的容器创建一个U 的容器,正如其他人提到的那样,要查找的算法是std::transform

如果你没有使用 C++ 11,这里是 std::transform 用法:

#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
#include <sstream>

std::string Transformer(double d)
{
    std::ostringstream doubleStr;
    doubleStr << d;
    return doubleStr.str();
}

int main()
{
    std::vector<double> doubleVec;
    doubleVec.push_back(1.0);
    doubleVec.push_back(2.1);
    doubleVec.push_back(3.2);

    std::vector<std::string> doubleStr;
    std::transform(doubleVec.begin(), doubleVec.end(), std::back_inserter(doubleStr), Transformer);
    std::copy(doubleStr.begin(), doubleStr.end(), std::ostream_iterator<std::string>(std::cout, "  "));
}

输出: 1 2.1 3.2

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 2014-05-16
    • 1970-01-01
    • 2013-03-15
    • 2012-03-02
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多