Sorting a multimap in alphabetical order

closed account (EwCjE3v7)
How can I sort a multimap in alphabetical order? I would think it would go something like below but that gives me a segmentation fault.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool alpha_order(const string ls, const string rs)
{
	return ls < rs;
}

int main()
{	
	multimap<string, string, decltype(alpha_order)*> authors = {{"Charlie Wilson", "Gone Far"},
								{"James Wilson", "The Water"},
								{"Charlie Wilson", "Clocks Gone"}};
	
	

	return 0;
}
Last edited on
Just use the default for the comparison function. (The default uses the < operator.)

1
2
3
4
5
6
7
int main()
{	
    std::multimap< std::string, std::string > authors = { { "Charlie Wilson", "Gone Far" },
                                                          { "James Wilson", "The Water" },
                                                          { "Charlie Wilson", "Clocks Gone" } };
    // ...
}
closed account (EwCjE3v7)
Oh that was a little stupid of me. Keys are sorted alphabetically, how may I sort the values alphabetically if the authors name was the same.

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{	
	multimap<string, string> authors = {{"Charlie Wilson", "Gone Far"},
										{"James Wilson", "The Water"},
										{"Charlie Wilson", "Clocks Gone"}};
	
	for (const auto &w : authors) {
		cout << w.first << " : " << w.second << endl;
	}
	

	return 0;
}


output:


Charlie Wilson : Gone Far
Charlie Wilson : Clocks Gone
James Wilson : The Water



I would like it to be like this;


Charlie Wilson : Clocks Gone
Charlie Wilson : Gone Far
James Wilson : The Water

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <set>
#include <map>
#include <utility>

int main()
{
    std::multimap< std::string, std::string > authors =
    {
        { "Charlie Wilson", "Gone Far" },
        { "James Wilson", "The Water" },
        { "Charlie Wilson", "Clocks Gone" },
        { "James Wilson", "Zebra" },
        { "James Wilson", "Aardvark" },
        { "Charlie Wilson", "Fargone Clocks" }
    };

    std::set< std::pair< std::string, std::string > > books( authors.begin(), authors.end() ) ;
    for( const auto& pair : books )
        std::cout << "author: '" << pair.first << "' book: '" << pair.second << "'\n" ;
}

http://coliru.stacked-crooked.com/a/bf659cd8db10c984
I believe that multimap has no guarantee on the order of the values that share a common key. So you will have to sort them yourself, or you could use a map<string, set<string> > instead. This would map an author to a set of titles. The titles would also be sorted alphabetically.
closed account (EwCjE3v7)
@JLBorges Thank you :)

@dhayden That would not work because the books would not be corresponding to the right authors.
That would not work because the books would not be corresponding to the right authors.


Read dhayden post more carefully.

He suggested using
map<string>, set<string> >

The authors entries would be unique because it is a map, not a multimap.
Each author then has it's own set<> of titles which would be in alphabetical order.

When you go to add an author and title, you would have to search to see if the author exists, if so, then you would add just the title to the set<> for that author. If the author does not exist, you would add the author to the map and the title to that author's set.


It would work. Though it would change the structure of your program (and maintaining that structure throughout the program may be somewhat wasteful, unless most authors had several books against their name).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <set>
#include <map>
#include <utility>

int main()
{
    std::map< std::string, std::set<std::string> > authors =
    {
        { "Charlie Wilson", { "Gone Far", "Clocks Gone", "Fargone Clocks" } },
        { "James Wilson", { "The Water", "Zebra", "Aardvark" } }
    };

    authors[ "Charlie Wilson" ].insert( "Clocks Gone Far" ) ;
    authors[ "Borges" ].insert( "The Garden of Forking Paths" ) ;

    for( const auto& pair : authors )
    {
        std::cout << "\nauthor: '" << pair.first << "'\n" ;
        for( const auto& str : pair.second ) std::cout << "\tbook: '" << str << "'\n" ;
    }
}

http://coliru.stacked-crooked.com/a/9b3e9a2825c96415
Last edited on
Topic archived. No new replies allowed.