我想从std::vector<std::string>构建一个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();
}我还能怎么做呢?
发布于 2013-09-10 01:30:05
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 (MSVC2010的子集)
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's algorithm,甚至比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的定义已经被altered,以便在追加到累加器时使用std::move,因此从C++20开始,accumulate将是字符串的O(n),并且可以用作一行程序:
std::string s = std::accumulate(v.begin(), v.end(), std::string{});发布于 2013-03-12 03:43:12
您可以使用<numeric>头中的std::accumulate()标准函数(它之所以有效,是因为为返回两个参数连接的strings定义了operator +重载):
#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周期:
#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!"
}发布于 2014-05-18 01:44:29
我个人的选择是基于范围的for循环,就像在Oktalist's answer中一样。
Boost还提供了一个很好的解决方案:
#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
https://stackoverflow.com/questions/15347123
复制相似问题