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

新手上路,请多包涵

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

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

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

我还能怎么做?

原文由 WilliamKF 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 723
2 个回答

C++03

 std::string s;
for (std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i)
    s += *i;
return s;

C++11 (MSVC 2010 子集)

 std::string s;
std::for_each(v.begin(), v.end(), [&](const std::string &piece){ s += piece; });
return s;

C++11

 std::string s;
for (const auto &piece : v) s += piece;
return s;

不要使用 std::accumulate 进行字符串连接,它是经典 的 Schlemiel the Painter 算法,甚至比在 C 中使用 strcat 的通常示例更糟糕。没有 C++11 移动语义,它为向量的每个元素产生两个不必要的累加器副本。即使使用移动语义,它仍然会为每个元素产生一个不必要的累加器副本。

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

std::accumulate 对于字符串来说是 O(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` 的定义已 [更改](http://wg21.link/p0616r0) 为使用 `std::move` ,因此从 C++20 开始, `accumulate` 将是 **O(n)** 对于字符串,并且可以用作单行:

std::string s = std::accumulate(v.begin(), v.end(), std::string{});

”`

原文由 Oktalist 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果不需要尾随空格,请使用 accumulate 定义在 <numeric> 和自定义连接 lambda。

 #include <iostream>
#include <numeric>
#include <vector>

using namespace std;

int main() {
    vector<string> v;
    string s;

    v.push_back(string("fee"));
    v.push_back(string("fi"));
    v.push_back(string("foe"));
    v.push_back(string("fum"));

    s = accumulate(begin(v), end(v), string(),
                   [](string lhs, const string &rhs) { return lhs.empty() ? rhs : lhs + ' ' + rhs; }
    );
    cout << s << endl;
    return 0;
}

输出:

 fee fi foe fum

原文由 user9494810 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题