the exercise here is to merge 2 sorted user lists so that the resulting list is sorted and has no duplicates. It seemed logical to me to use std::set<std::string> for the user lists, since it sorts them from the beginning.
This code works, but seems a bit ugly to me, because I switch to vector before using set_union (reason below):
Code:
#include <string>
#include <set>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
std::string temp = "";
int counter = 1;
std::set<std::string> mat_friend, pat_friend;
std::ostream_iterator<std::string, char> out(std::cout, "\n");
// create Mat's list
while (true)
{
std::cout << "Enter Mat's friend " << counter << " ('q' to quit): ";
std::cin >> temp;
++counter;
if (temp == "q" || temp == "Q")
break;
mat_friend.insert(temp);
}
std::cout << "Mat's friends:\n";
copy(mat_friend.begin(), mat_friend.end(), out);
std::cout << std::endl;
// reset variables
counter = 1;
temp = "";
// create Pat's list
while (true)
{
std::cout << "Enter Pat's friend " << counter << " ('q' to quit): ";
std::cin >> temp;
++counter;
if (temp == "q" || temp == "Q")
break;
pat_friend.insert(temp);
}
std::cout << "Pat's friends:\n";
copy(pat_friend.begin(), pat_friend.end(), out);
std::cout << std::endl;
// merge the sets
std::vector<std::string> all_friend(mat_friend.size() + pat_friend.size());
set_union(mat_friend.begin(), mat_friend.end(), pat_friend.begin(), pat_friend.end(),
all_friend.begin());
// show result
std::cout << "All friends:\n";
copy(all_friend.begin(), all_friend.end(), out);
std::cout << std::endl;
std::cout << "\nAdios, amigo!\n";
return 0;
}
The problem is that if I just declare all_friend with the simple
Code:
std::set<std::string> all_friend;
I get a runtime error when the program hits set_union. The error messages are a bit over my head, but what seems logical is that there's no memory allocated to hold whatever set_union is throwing in the direction of all_friend.begin().
How would you guys solve this? the vector version is nice and short, but i find the switch to vector aesthetically displeasing.
But to stick with std::set, the only strategy i can think of is to say
Code:
std::set<std::string> all_friend(mat_friend);
and then iterate through pat_friend using insert at each step (which, to refer back to MK's issue, would require setting up an insert-like function of the appropriate type if I want to use for_each).
Anyhow, all that seems like a lot of trouble to go to when std::vector and set_union solve the problem so quickly.
Any ideas for a more elegant solution?