2

Suggest any method to sort a multimap for both key and its values. For example- Input- (5,1), (1,9), (1,1), (5,2), (1,2) And the Output must be- (1,1), (1,2), (1,9), (5,1), (5,2).

Aman
  • 25
  • 1
  • 1
  • 6

4 Answers4

4

The answer is emplace_hint. Pseudo code will look like that:-

insert_with_hint(M mmap, K key, V Value)
{
    auto i1 = mmap.equal_range(Key);
    for (auto i2 = i1.first; i2 != i1.second; ++i2)
    {
     if (i2->second > Key) { // <-- Here add your sorting criteria
           mmap.emplace_hint(i2,Key,Value)
      return
     }
   }
   mmap.emplace(Key,Value)
}
Boris
  • 1,311
  • 13
  • 39
  • Should be the accepted answer.Helped me in a scenario where I still don't mind additinal effort when creating the `std::multimap`. Allows access via key and `equal_range()` (thus `std::set` or `std::multiset` are not an alternative), while having more efficient comparisons for the values at runtime. Had to switch to g++ 4.8 (4.7 does not provide `emplace()` and `emplace_hint()` even with `std=c++11`. – radix Oct 27 '16 at 10:05
  • This answer is very helpful. However, shouldn't it compare `i2->second` to `Value` instead of `Key`? Also, the capitalization of key causes some confusion as well. – Ben Jones Jul 04 '19 at 16:15
1

If you really want to use multimap then the ordering of values is always the order in which you insert them and that cannot be changed unfortunately i.e in the example given in the question they are stored as (1,9), (1,1), (1,2), (5, 1), (5,2)

If you can relax a bit on the multimap, then you can use a set and store the above pairs in the set and define the ordering you desire on the pair definition. Since, the set stores it's values in sorted order, it will store your pairs also in the ordering you define.

  • 3
    This is incorrect - elements inserted into a multimap are sorted by the key used. The order in which elements are inserted does not affect the order in which they are stored. – millinon Jan 19 '14 at 10:22
  • I meant to say that in a multimap, the pairs are stored in the order of their keys but there is no proper ordering on the basis of their values (values as in the (key, value) pair) i.e. in the example given in the question they are stored as (1,9),(1,1),(1,2),(5,1),(5,2). I think you misunderstood my answer – user3203860 Jan 19 '14 at 10:32
1

You just need to copy all its elements to a multiset<pair<int, int>>:

multimap<int, int> a;
a.insert(pair<int, int>(5, 1));
a.insert(pair<int, int>(1, 9));
a.insert(pair<int, int>(1, 1));
a.insert(pair<int, int>(5, 2));
a.insert(pair<int, int>(1, 2));

multiset<pair<int, int>> b;
for (multimap<int, int>::iterator i=a.begin(); i!=a.end(); i++)
    b.insert(pair<int, int>((*i).first, (*i).second));

After this, multiset<pair<int, int>> b is what you want, i.e. {(1,1), (1,2), (1,9), (5,1), (5,2)}.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
0

Change the key to include both values. Design a comparator which compares the two pairs of values in the correct order.

Having done this you can use multiset instead of a multimap.

John Dibling
  • 99,718
  • 31
  • 186
  • 324