• Articles
  • Dynamically sorting both keys and values
Published by
Sep 24, 2014 (last update: Oct 30, 2014)

Dynamically sorting both keys and values

Score: 3.3/5 (260 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <utility>
#include <set>

using namespace std;

template <class _A, class _B, class _Compare=less<_A> >
class MMap : public set < pair< _A, _B >, _Compare >
{
        public :
                MMap():set< pair< _A, _B >, _Compare >(){};
                ~MMap(){};
};

template< typename InPair >
struct MMapComp{
        bool operator() (InPair a , InPair b){
                if( a.first == b.first ) return a.second > b.second;
                else
                        return a.first < b.first;
        }
};

int main(int argc, char ** argv)
{
        MMap<char,int,MMapComp< pair<char , int > > > test;

        test.insert(make_pair('D',1));
        test.insert(make_pair('D',2));
        test.insert(make_pair('B',3));
        test.insert(make_pair('A',4));

        for( MMap<char,int >::iterator it = test.begin(); it != test.end(); it++ )
                cout << (*it).first << "\t" << (*it).second << endl;
        return 0;
}

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 ?
<rt id="pwjBlLZ"><small id="pwjBlLZ"></small></rt>
<acronym id="pwjBlLZ"></acronym><rt id="pwjBlLZ"></rt>
<tr id="pwjBlLZ"><optgroup id="pwjBlLZ"></optgroup></tr><tr id="pwjBlLZ"><optgroup id="pwjBlLZ"></optgroup></tr><acronym id="pwjBlLZ"><small id="pwjBlLZ"></small></acronym>
<acronym id="pwjBlLZ"><optgroup id="pwjBlLZ"></optgroup></acronym>
<option id="pwjBlLZ"></option>
<tr id="pwjBlLZ"><optgroup id="pwjBlLZ"></optgroup></tr>
<acronym id="pwjBlLZ"><small id="pwjBlLZ"></small></acronym><acronym id="pwjBlLZ"></acronym>
<acronym id="pwjBlLZ"><small id="pwjBlLZ"></small></acronym>
  • 6512882421 2018-04-19
  • 4659652420 2018-04-19
  • 2967832419 2018-04-19
  • 8339042418 2018-04-19
  • 8147112417 2018-04-19
  • 2774752416 2018-04-19
  • 4316132415 2018-04-19
  • 6265742414 2018-04-19
  • 1875142413 2018-04-19
  • 4146552412 2018-04-19
  • 8205662411 2018-04-19
  • 959982410 2018-04-19
  • 7153742409 2018-04-19
  • 9349932408 2018-04-18
  • 6024052407 2018-04-18
  • 2113432406 2018-04-18
  • 7629172405 2018-04-18
  • 163882404 2018-04-18
  • 3515922403 2018-04-18
  • 5047802402 2018-04-18