首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从std::vector<string>构造std::string?

如何从std::vector<string>构造std::string?
EN

Stack Overflow用户
提问于 2013-03-12 03:39:48
回答 8查看 81.9K关注 0票数 55

我想从std::vector<std::string>构建一个std::string

我可以使用std::stringsteam,但想象一下有一种更短的方法:

代码语言:javascript
复制
std::string string_from_vector(const std::vector<std::string> &pieces) {
  std::stringstream ss;

  for(std::vector<std::string>::const_iterator itr = pieces.begin();
      itr != pieces.end();
      ++itr) {
    ss << *itr;
  }

  return ss.str();
}

我还能怎么做呢?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2013-09-10 01:30:05

C++03

代码语言:javascript
复制
std::string s;
for (std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i)
    s += *i;
return s;

C++11 (MSVC2010的子集)

代码语言:javascript
复制
std::string s;
std::for_each(v.begin(), v.end(), [&](const std::string &piece){ s += piece; });
return s;

C++11

代码语言:javascript
复制
std::string s;
for (const auto &piece : v) s += piece;
return s;

对于字符串连接,请不要使用std::accumulate ,这是一个经典的Schlemiel the Painter's algorithm,甚至比C中使用strcat的常见示例还要糟糕。如果没有C++11移动语义,它会为向量的每个元素产生两个不必要的累加器副本。即使使用移动语义,它仍然会为每个元素产生一个不必要的累加器副本。

上面的三个例子是O(n)

对于字符串,std::accumulateO(n²)

对于字符串,您可以通过提供一个自定义函数器来实现std::accumulate O(n):

std::string s= std::accumulate(v.begin(),v.end(),std::string{},std::string &s, const std::string &piece -> decltype(auto) { return s += piece;});

注意,s必须是对非常数的引用,lambda返回类型必须是引用(因此是decltype(auto)),主体必须使用+=而不是+

C++20

在预计将成为C++20的当前草案中,std::accumulate的定义已经被altered,以便在追加到累加器时使用std::move,因此从C++20开始,accumulate将是字符串的O(n),并且可以用作一行程序:

代码语言:javascript
复制
std::string s = std::accumulate(v.begin(), v.end(), std::string{});
票数 105
EN

Stack Overflow用户

发布于 2013-03-12 03:43:12

您可以使用<numeric>头中的std::accumulate()标准函数(它之所以有效,是因为为返回两个参数连接的strings定义了operator +重载):

代码语言:javascript
复制
#include <vector>
#include <string>
#include <numeric>
#include <iostream>

int main()
{
    std::vector<std::string> v{"Hello, ", " Cruel ", "World!"};
    std::string s;
    s = accumulate(begin(v), end(v), s);
    std::cout << s; // Will print "Hello, Cruel World!"
}

或者,您可以使用更高效、更小的for周期:

代码语言:javascript
复制
#include <vector>
#include <string>
#include <iostream>

int main()
{
    std::vector<std::string> v{"Hello, ", "Cruel ", "World!"};
    std::string result;
    for (auto const& s : v) { result += s; }
    std::cout << result; // Will print "Hello, Cruel World!"
}
票数 37
EN

Stack Overflow用户

发布于 2014-05-18 01:44:29

我个人的选择是基于范围的for循环,就像在Oktalist's answer中一样。

Boost还提供了一个很好的解决方案:

代码语言:javascript
复制
#include <boost/algorithm/string/join.hpp>
#include <iostream>
#include <vector>

int main() {

    std::vector<std::string> v{"first", "second"};

    std::string joined = boost::algorithm::join(v, ", ");

    std::cout << joined << std::endl;
}

这将打印:

first,second

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15347123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档