Reputation: 682
I've been reading Accelerated C++ and I have to say it's an interesting book.
In chapter 6, I have to use a function from <algorithm> to concatenate from a vector<string> into a single string. I could use accumulate, but it doesn't help because string containers can only push_back characters.
int main () {
using namespace std;
string str = "Hello, world!";
vector<string> vec (10, str);
// Concatenate here?
return 0;
}
How do I join the strings together?
Upvotes: 30
Views: 51718
Reputation: 6416
How about std::copy?
std::ostringstream os;
std::copy( vec_strings.begin(), vec_string.end(), std::ostream_iterator<std::string>( os ) );
std::cout << os.str() << std::endl;
Upvotes: 19
Reputation: 1971
This answer is an improved version of the one from @PrasoonSaurav by adding a helpful sep
argument.
inline std::string joinStrings(std::vector<std::string> arr, std::string sep) {
std::string out = arr[0];
for(unsigned int i = 1; i < arr.size(); i++) {
out += sep + arr[i];
}
return out;
}
// Overload function parameter to add default value for the separator
inline std::string joinStrings(std::vector<std::string> arr) {
return joinStrings(arr, std::string(", "));
}
Upvotes: 0
Reputation:
Assuming this is question 6.8, it doesn't say you have to use accumulate - it says use "a library algorithm". However, you can use accumulate:
#include <numeric>
int main () {
std::string str = "Hello World!";
std::vector<std::string> vec(10,str);
std::string a = std::accumulate(vec.begin(), vec.end(), std::string(""));
std::cout << a << std::endl;
}
All that accumulate does is set 'sum' to the third parameter, and then for all of the values 'val' from first parameter to second parameter, do:
sum = sum + val
it then returns 'sum'. Despite the fact that accumulate is declared in <numeric>
it will work for anything that implements operator+()
Note: This solution, while elegant, is inefficient, as a new string will be allocated and populated for each element of vec
.
Upvotes: 73
Reputation: 2118
The following snippet compiles in Visual C++ 2012 and uses a lambda function:
int main () {
string str = "Hello World!";
vector<string> vec (10,str);
stringstream ss;
for_each(vec.begin(), vec.end(), [&ss] (const string& s) { cat(ss, s); });
cout << ss.str() << endl;
}
The accumulate
example in the 1st answer is elegant, but as sellibitze pointed out, it reallocates with each concatenation and scales at O(N²). This for_each
snippet scales at about O(N). I profiled both solutions with 100K strings; the accumulate
example took 23.6 secs, but this for_each
snippet took 0.054 sec.
Upvotes: 14
Reputation: 92864
I am not sure about your question.Where lies the problem? Its just a matter of a loop.
#include<vector>
#include<string>
#include<iostream>
int main ()
{
std::string str = "Hello World!";
std::vector<string> vec (10,str);
for(size_t i=0;i!=vec.size();++i)
str=str+vec[i];
std::cout<<str;
}
EDIT :
Use for_each()
from <algorithm>
Try this:
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
string i;
void func(string &k)
{
i+=k;
}
int main () {
string str = "Hello World!";
vector<string> vec (10,str);
for_each(vec.begin(),vec.end(),func);
cout<<i;
return 0;
}
Upvotes: 7