0

I need to design a data structure that basically stores key-value pairs with key being an integer and its value a string.

Condition 1: There could be multiple values associated with a Key.

Condition 2: I need to print all the keys stored in this map in descending order.

Condition 3: Though the Keys(integers) are printed in Descending order, their corresponding values(strings) must be printed in lexicographic(sorted in ascending) order.

Sample Input:

78 Eve                                      
99 Bob                                       
78 Alice                                    

Expected Output:

99 Bob
78 Alice
78 Eve

Notice the keys are in descending order, while the values are in ascending order.

To do this I have come up with below code in C++:

#include <iostream>
#include <map>

using namespace std;

int main()
{
    int N;
    string name;
    int marks;
    multimap<int, string, greater<int>> studMap;
    multimap<int, string, greater<int>>::iterator itBeg, itEnd;
    typedef multimap<int, string, greater<int>>::iterator mapIter;

    cin >> N;   // total no. of key-value pairs input by user

    while (N--)
    {
        cin >> name >> marks;  // pairs of value-key input by user - N times
        studMap.insert(pair<int, string>(marks, name));
    }

    for (itBeg = studMap.begin(); itBeg != studMap.end(); itBeg = itEnd)
    {
        marks = itBeg->first;

        pair<mapIter, mapIter> keyRange = studMap.equal_range(marks);

        for (itEnd = keyRange.first; itEnd != keyRange.second; ++itEnd)
        {
            cout << marks << " " << itEnd->second << endl;
        }
    }  
    return 0;
}

But I am getting output as shown below:

99 Bob
78 Eve 
78 Alice

whereas I need pair(78, Alice) to be printed before (78, Eve)

jon hanson
  • 8,722
  • 2
  • 37
  • 61
Mohammed Raqeeb
  • 75
  • 2
  • 12

2 Answers2

2

I wouldn't use multimap. I'd use a map<int, set<string>>. The reason is you need both your keys and values sorted. A multimap is only going to sort the keys. By using a map of sets, the map will sort by keys and the set will sort by values (assuming you give it the right comparator).

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • this is probably easiest, but a multimap with a custom compare would do it too... – mark Jun 24 '15 at 21:40
  • No it wouldn't. The compare function is just passed the two keys to compare, not the keys and the values. If you're suggesting compare look up the values- ewww, that would be horrible performance. Or depending on implementation an inifinite recursion and stackdump. – Gabe Sechan Jun 24 '15 at 21:43
  • well, i was suggesting something a hair more hack-ish i suppose... along the lines of the custom compare could access the data itself for both components. i'm sure outside the scope of the learning exercise... – mark Jun 24 '15 at 21:49
  • @GabeSechan I modified my code to use the map > approach. All seems fine now. Thanks! – Mohammed Raqeeb Jun 25 '15 at 19:43
1

If you want to sort key-value pairs by both the key and the value, then you don't want a multimap, which doesn't provide any way to sort on values with the same key. You want a set of pairs, with a custom comparison function that sorts them in the order you want. Something like this (warning, code written off the top of my head, not tested):

using KeyValue = std::pair<int, std::string>;

struct CompareKeyValue {
    bool operator()(const KeyValue& lhs, const KeyValue& rhs) const {
        if (lhs.first != rhs.first)
            return lhs.first > rhs.first; // Reverse order
        else
            return lhs.second < rhs.second;
    }
};

std::set<KeyValue, CompareKeyValue> my_data;
Ross Smith
  • 3,719
  • 1
  • 25
  • 22
  • although that doesn't allow for non-unique keys... wait, why doesn't multimap work with custom compare? the compare needs to point to something that contains both aspects is all... – mark Jun 24 '15 at 21:37
  • It does allow for non-unique keys. It doesn't allow for non-unique key-value pairs, but if you want that, just use a multiset instead of a set. You can't give a multimap a comparison that looks at both key and value, it won't compile. – Ross Smith Jun 24 '15 at 21:44
  • The bigger problem to me is that if you need to check if there is any value for a given key, you can't. You can only check if a given pair is in the data structure. – Gabe Sechan Jun 24 '15 at 21:52