Thread: problems with set_union( ... )

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    242

    problems with set_union( ... )

    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?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What you are doing now is probably fine, but if you really want you can use back_inserter:
    Code:
    // merge the sets
    std::vector<std::string> all_friend;
    set_union(mat_friend.begin(), mat_friend.end(), pat_friend.begin(), pat_friend.end(),
        std::back_inserter(all_friend));
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    242
    yes, those are the iterators i was needing:
    Code:
    std::set<std::string> all_friend;
    set_union(mat_friend.begin(), mat_friend.end(), pat_friend.begin(), pat_friend.end(),
    	inserter(all_friend, all_friend.begin()));
    tx again!
    Last edited by Aisthesis; 03-10-2010 at 05:55 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. No clue how to make a code to solve problems!
    By ctnzn in forum C Programming
    Replies: 8
    Last Post: 10-16-2008, 02:59 AM
  2. String Manipulation problems -_-
    By Astra in forum C Programming
    Replies: 5
    Last Post: 12-13-2006, 05:48 PM
  3. Rendering problems (DirectX?)
    By OnionKnight in forum Tech Board
    Replies: 0
    Last Post: 08-17-2006, 12:17 PM
  4. contest problems on my site
    By DavidP in forum Contests Board
    Replies: 4
    Last Post: 01-10-2004, 09:19 PM
  5. DJGPP problems
    By stormswift in forum C Programming
    Replies: 2
    Last Post: 02-26-2002, 04:35 PM