0

I have a map defined like this

std::map<int,int> myMap;

After processing this map I want to treat it as a heap (based on the second value). I decided to use std::make_heap function.. which is defined like this...

template< class RandomIt, class Compare > void make_heap( RandomIt first, RandomIt last, Compare comp );

As this function requires a comparison function to be defined... I did it like this

bool compare(const std::pair<int,int> &frst, const std::pair<int,int> &scnd)

Now with this setup I call make_heap like this

std::make_heap(myMap.begin(), myMap.end(),compare);

But this gives me compilation error...

/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_heap.h: In function ‘void std::make_heap(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = std::_Rb_tree_iterator<std::pair<const int, int> >]’:
maxRepeatingNumber.cc:48:   instantiated from here /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_heap.h:357: error: no match for ‘operator-’ in ‘__last - __first’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include e/c++/4.1.2/bits/stl_bvector.h:182: note: candidates are: ptrdiff_t std::operator-(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/ c++/4.1.2/bits/stl_heap.h:360: error: no match for ‘operator-’ in ‘__last - __first’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_bvector.h:182: note: candidates are: ptrdiff_t std::operator-(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_heap.h:364: error: no match for ‘operator+’ in ‘__first + __parent’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_bvector.h:267: note: candidates are: std::_Bit_iterator std::operator+(ptrdiff_t, const std::_Bit_iterator&)

Compilation error gives me a hint that they may be because of make_heap requires random_access_iterator... but I am not sure on that.

Should I move to Function Objects (from plain function pointer)?

Any help?

vikrant
  • 393
  • 4
  • 15

2 Answers2

3

You cannot make a heap directly on a map. Map is sorted already by a key and you need a different partial sorting. You can copy all map values to a vector and make a heap from it.

Edit:

If you need to modify your map and maintain the heap, you can implement something like multi-index container when one of indexes would be actually heap-powered.

Andriy Tylychko
  • 15,967
  • 6
  • 64
  • 112
1

Agreed with @Andy. Map is already sorted by key so you can't make heap directly on it. To solve similar problem i created a vector of pair with map value as first element and key as second element and then make heap. It won't require any compactor parameter for max heap.

For example: For map "map m" create vector using below code and then make heap.

for(it=m.begin(); it != m.end(); it++)
    v.push_back(make_pair(it->second,it->first));   

make_heap(v.begin(),v.end(),sort_v());

This will work and top element would be returned at any point of time.

preeti
  • 11
  • 2
  • Incidentally, if the key or value are somewhat costly to copy you can even make the vector contain directly map iterators instead of value-key pairs. – Matteo Italia Apr 27 '16 at 20:38