Thread: copying differents maps

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    630

    copying differents maps

    Hello

    What is the best way to convert
    Code:
    std::map<std::string, std::set<std::string> >
    to:
    Code:
    std::map<std::string, std::vector<std::string> >
    Should I do it for each key separately with building std::vector individually from std::set?

    I want to change the datatype because I need random access (iterator).

    Many thanks in advance!
    Last edited by l2u; 10-12-2008 at 07:33 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What's the difference?

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I think you meant one of them to be:
    Code:
    std::map<std::string, std::vector<std::string> >
    Right?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    And I'm pretty sure "I need to have a random access iterator" is no reason to choose a data structure. The difference between set and vector is that set only allows unique elements to be stored, and there's no notion of which order things were added in; while vector is the opposite.

    First, figure out which makes sense for your data, then we'll look at the algorithms.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I'd do as tabstop suggests and make sure you're converting it for the right reasons first. But if you actually need to do it, I believe something like this should work:
    Code:
    #include <string>
    #include <map>
    #include <set>
    #include <vector>
    
    
    int main()
    {
    	typedef std::map<std::string, std::set<std::string> >		mapStrSet;
    	typedef std::map<std::string, std::vector<std::string> >	mapStrVector;
    
    	mapStrSet	map_str_set;
    	mapStrVector	map_str_vector;
    
    	// Fill the map_str_set
    	// ...
    
    	for ( mapStrSet::iterator it = map_str_set.begin(); it != map_str_set.end(); ++it )
    	{
    		map_str_vector.insert( mapStrVector::value_type(it->first, std::vector<std::string>( it->second.begin(), it->second.end() )) );
    	}
    
    	return 0;
    }
    Although you might also convert the for loop into a std::for_each algorithm, but I'll leave that to you to figure out, since I'm too lazy to try it right now.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    630
    Quote Originally Posted by cpjust View Post
    I think you meant one of them to be:
    Code:
    std::map<std::string, std::vector<std::string> >
    Right?
    Thats right. My mistake.

  7. #7
    Registered User
    Join Date
    May 2006
    Posts
    630
    I have a server that stores a std::set with unique elements which is then serialized and sent over tcp ip connection to client which stores it as a vector because it needs to access those elements randomly.

    I have read storing it as a vector (copying to vector) would be faster than accessing std::set at random positions with stl algorithms. Is that right?

  8. #8
    Registered User
    Join Date
    Aug 2008
    Posts
    188
    only adding to the end? use vector.
    adding beginning or end? use dequeue.
    adding/removing in the middle? use set.

    and what do you mean randomly?

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Given that the incoming set is ordered, just what do you mean by accessing them randomly?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Registered User
    Join Date
    May 2006
    Posts
    630
    I use rand() to select/get elements at random position(s).
    Like with vector:
    Code:
    std::vector<std::string> m_vector;
    m_vector[make_random_number(0, m_vector.size())];
    where make_random_number(0, m_vector.size()) returns a number betwen 0 and m_vector.size()

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I apologize if you've already answered this question, but why not start with a sorted vector instead of the set?

    Using copy with a back_inserter should work if you keep the current setup.

  12. #12
    Registered User
    Join Date
    May 2006
    Posts
    630
    Quote Originally Posted by Daved View Post
    I apologize if you've already answered this question, but why not start with a sorted vector instead of the set?

    Using copy with a back_inserter should work if you keep the current setup.
    I never thought of that..
    And after sorting it use unique algorithm so that the vector would keep unique elements at the first place and there wouldnt be need of changing types afterwards?

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The sorted vector idea works best if you add all your elements at the start, then sort them (and make them unique if necessary) before using them. If the data must be unique, it works best if you don't have a lot of duplicates.

    If you do have a lot of duplicates, then adding everything to the vector first could waste a lot of space (although you might be able to make the data unique in stages to reduce that waste).

    If you don't insert all the elements at the beginning, and instead do it as you go (meaning you insert some elements, then use the vector, then insert some more, then use the vector, etc), then a vector is a bad idea because you would either have to insert into the middle (which is costly) or sort the container and make it unique each time you add something. Both options might be slower than using the set and then at the end copying to a vector, but it sounds like this might not be a problem for you if you're just filling the container before sending it.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by cpjust View Post
    Code:
    #include <string>
    #include <map>
    #include <set>
    #include <vector>
    
    
    int main()
    {
    	typedef std::map<std::string, std::set<std::string> >		mapStrSet;
    	typedef std::map<std::string, std::vector<std::string> >	mapStrVector;
    
    	mapStrSet	map_str_set;
    	mapStrVector	map_str_vector;
    
    	// Fill the map_str_set
    	// ...
    
    	for ( mapStrSet::iterator it = map_str_set.begin(); it != map_str_set.end(); ++it )
    	{
    		map_str_vector.insert(
    			mapStrVector::value_type
    			(
    				it->first,
    				std::vector<std::string>( it->second.begin(), it->second.end() )
    			) );
    	}
    
    	return 0;
    }
    Wow, horrible code for something that should be something so easy.
    I had to take the liberty of splitting that long line so I could actually see what it was doing.
    Last edited by Elysia; 10-13-2008 at 02:12 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    l2u, what are the values for the size of the map and the sizes of the sets/vectors in the value portion? What's the average and the range of those values generally look like? It's best not to "pessimize" by choosing a poor container/algorithm, but depending on those values it might be best to use the simpler solution rather than concentrate on finding the ultimate solution.


    >> Wow, horrible code for something that should be something so easy. <<
    This type of comment is useless (or worse) without an explanation or other example. Although if you'd care to start a discussion about it I'd hope it doesn't derail the thread.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Loading maps
    By divineleft in forum C++ Programming
    Replies: 1
    Last Post: 07-05-2006, 10:09 AM
  2. Hash_map, STL maps query
    By alvifarooq in forum C++ Programming
    Replies: 15
    Last Post: 06-07-2005, 09:07 AM
  3. Shallow/Deep copying, pointers
    By littleweseth in forum C++ Programming
    Replies: 3
    Last Post: 11-26-2003, 06:36 PM
  4. Finding terrain maps...
    By VirtualAce in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 09-25-2001, 07:44 PM
  5. Copying a file
    By rkjd2 in forum C++ Programming
    Replies: 5
    Last Post: 09-09-2001, 10:24 AM