nki*_*int 27 c++ string vector
我想用自定义分隔符将a的内容复制vector到一个long string.到目前为止,我已经尝试过:
// .h
string getLabeledPointsString(const string delimiter=",");
// .cpp
string Gesture::getLabeledPointsString(const string delimiter) {
vector<int> x = getLabeledPoints();
stringstream s;
copy(x.begin(),x.end(), ostream_iterator<int>(s,delimiter));
return s.str();
}
Run Code Online (Sandbox Code Playgroud)
但我明白了
no matching function for call to ‘std::ostream_iterator<int, char, std::char_traits<char> >::ostream_iterator(std::stringstream&, const std::string&)’
Run Code Online (Sandbox Code Playgroud)
我试过charT*但我得到了
error iso c++ forbids declaration of charT with no type
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用char,ostream_iterator<int>(s,&delimiter)
但我在字符串中得到奇怪的字符.
任何人都可以帮助我理解编译器在这里期待什么吗?
jpa*_*cek 22
copy(x.begin(),x.end(), ostream_iterator<int>(s,delimiter.c_str()));
Run Code Online (Sandbox Code Playgroud)
这样,你得到一个const char*指向字符串,这是你的ostream_operator期望std::string.
max*_*ndr 13
C++ 11:
vector<string> x = {"1", "2", "3"};
string s = std::accumulate(std::begin(x), std::end(x), string(),
[](string &ss, string &s)
{
return ss.empty() ? s : ss + "," + s;
});
Run Code Online (Sandbox Code Playgroud)
Sha*_*531 12
另一种方法:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
template <typename T>
string join(const T& v, const string& delim) {
ostringstream s;
for (const auto& i : v) {
if (&i != &v[0]) {
s << delim;
}
s << i;
}
return s.str();
}
int main() {
cout << join(vector<int>({1, 2, 3, 4, 5}), ",") << endl;
}
Run Code Online (Sandbox Code Playgroud)
(c ++ 11基于范围的循环和'自动'虽然)
std::string Gesture::getLabeledPointsString(const std::string delimiter) {
return boost::join(getLabeledPoints(), delimiter);
}
Run Code Online (Sandbox Code Playgroud)
我不相信getLabeledPointsString在这一点上介绍;)
小智 7
这是上面已经提供的两个答案的扩展,因为运行时性能似乎是评论中的主题.我会把它添加为评论,但我还没有这个特权.
我使用Visual Studio 2015测试了2个运行时性能的实现:
使用stringstream:
std::stringstream result;
auto it = vec.begin();
result << (unsigned short)*it++;
for (; it != vec.end(); it++) {
result << delimiter;
result << (unsigned short)*it;
}
return result.str();
Run Code Online (Sandbox Code Playgroud)
使用累积:
std::string result = std::accumulate(std::next(vec.begin()), vec.end(),
std::to_string(vec[0]),
[&delimiter](std::string& a, uint8_t b) {
return a + delimiter+ std::to_string(b);
});
return result;
Run Code Online (Sandbox Code Playgroud)
发布版本的运行时性能接近于几个细微之处.
累积实现略快(20-50ms,在256个元素向量的1000次迭代中总运行时间的约10-30%(~180ms)).但是,accumulate当alambda函数的参数通过引用传递时,实现速度更快.a按值传递参数导致类似的运行时差异有利于stringstream实现.该accumulate实施也提高了一些,当结果字符串直接返回,而不是分配给立刻返回一个局部变量.YMMV与其他C++编译器.
Debug构建的使用速度慢了5-10倍,accumulate所以我认为上面几条评论中提到的额外字符串创建由优化器解决.
我使用的是寻找一个具体实施vector的uint8_t值.完整的测试代码如下:
#include <vector>
#include <iostream>
#include <sstream>
#include <numeric>
#include <chrono>
using namespace std;
typedef vector<uint8_t> uint8_vec_t;
string concat_stream(const uint8_vec_t& vec, string& delim = string(" "));
string concat_accumulate(const uint8_vec_t& vec, string& delim = string(" "));
string concat_stream(const uint8_vec_t& vec, string& delimiter)
{
stringstream result;
auto it = vec.begin();
result << (unsigned short)*it++;
for (; it != vec.end(); it++) {
result << delimiter;
result << (unsigned short)*it;
}
return result.str();
}
string concat_accumulate(const uint8_vec_t& vec, string& delimiter)
{
return accumulate(next(vec.begin()), vec.end(),
to_string(vec[0]),
[&delimiter](string& a, uint8_t b) {
return a + delimiter + to_string(b);
});
}
int main()
{
const int elements(256);
const int iterations(1000);
uint8_vec_t test(elements);
iota(test.begin(), test.end(), 0);
int i;
auto stream_start = chrono::steady_clock::now();
string join_with_stream;
for (i = 0; i < iterations; ++i) {
join_with_stream = concat_stream(test);
}
auto stream_end = chrono::steady_clock::now();
auto acc_start = chrono::steady_clock::now();
string join_with_acc;
for (i = 0; i < iterations; ++i) {
join_with_acc = concat_accumulate(test);
}
auto acc_end = chrono::steady_clock::now();
cout << "Stream Results:" << endl;
cout << " elements: " << elements << endl;
cout << " iterations: " << iterations << endl;
cout << " runtime: " << chrono::duration<double, milli>(stream_end - stream_start).count() << " ms" << endl;
cout << " result: " << join_with_stream << endl;
cout << "Accumulate Results:" << endl;
cout << " elements: " << elements << endl;
cout << " iterations: " << iterations << endl;
cout << " runtime: " << chrono::duration<double, milli>(acc_end - acc_start).count() << " ms" << endl;
cout << " result:" << join_with_acc << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
string join(const vector<string> & v, const string & delimiter = ",") {
string out;
if (auto i = v.begin(), e = v.end(); i != e) {
out += *i++;
for (; i != e; ++i) out.append(delimiter).append(*i);
}
return out;
}
Run Code Online (Sandbox Code Playgroud)
几点: