You are on page 1of 2

Dynamically sorting both keys and values

Score: 3.5/5 (337 votes)

Well, you might have faced this problem in your coding life. Also you might know the answer already. The
problem was about the std::map or say std::multimap, both of them are special type of containers who
can sort the items by a comparing function pointer(or a built-in one like std::less). They sort it when you
are inserting a new item, that's of course so handy, because you don't wanna call a sorting function
every time you need to! Actually you will never explicitly call any sorting function on your map or
multimap, coz it's already sorted! Now here's my problem-
Say, I have a map like this -
D - 1
D - 2
B - 3
A - 4

Now I need to sort them like this -


A - 4
B - 3
D - 2
D - 1
Here's the explanation of this sorting- first elements(A,B,D) will be sorted in ascending order A --> B -->
D regardless of the second element, secondly if the first elements are equal (i.e 2 Ds here) then they will
be sorted as the descending order of their corresponding second element.
Using std::multimap will end-up with only the first sorting part, so I took advantage of templates and
inheritances. Here's the code -

1 #include <iostream>  Edit &


2 #include <utility> Run
3 #include <set>
4
5 using namespace std;
6
7 template <class _A, class _B, class _Compare=less<_A> >
8 class MMap : public set < pair< _A, _B >, _Compare >
9{
10 public :
11 MMap():set< pair< _A, _B >, _Compare >(){};
12 ~MMap(){};
13 };
14
15 template< typename InPair >
16 struct MMapComp{
17 bool operator() (InPair a , InPair b){
18 if( a.first == b.first ) return a.second > b.second;
19 else
20 return a.first < b.first;
21 }
22 };
23
24 int main(int argc, char ** argv)
25 {
26 MMap<char,int,MMapComp< pair<char , int > > > test;
27
28 test.insert(make_pair('D',1));
29 test.insert(make_pair('D',2));
30 test.insert(make_pair('B',3));
31 test.insert(make_pair('A',4));
32
33 for( MMap<char,int >::iterator it = test.begin(); it !=
34 test.end(); it++ )
35 cout << (*it).first << "\t" << (*it).second << endl;
36 return 0;
37 }

And here's the output -

A 4
B 3
D 2
D 1

Ok, I apologize for my undocumented code :) But it's not so hard to read actually. Is it ?

You might also like