Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find the minimum value in a map?

Tags:

I have a map and I want to find the minimum value (right-hand side) in the map. Here is how I did it:

bool compare(std::pair<std::string ,int> i, pair<std::string, int> j) {   return i.second < j.second; } //////////////////////////////////////////////////// std::map<std::string, int> mymap;  mymap["key1"] = 50; mymap["key2"] = 20; mymap["key3"] = 100;  std::pair<char, int> min = *min_element(mymap.begin(), mymap.end(), compare);  std::cout << "min " << min.second<< " " << std::endl; 

The code above works fine and I'm able to get the minimum value. However, when I put this code inside my class as follows, it doesn't seem to work:

int MyClass::getMin(std::map<std::string, int> mymap) {   std::pair<std::string, int> min = *min_element(mymap.begin(), mymap.end(),                                                   (*this).compare);                                                  // Error probably due to "this".   return min.second;  }  bool MyClass::compare(     std::pair<std::string, int> i, std::pair<std::string, int> j) {    return i.second < j.second;  } 

How can I make the code work with my class? Also, is there a better solution which doesn't require writing the additional compare function?

like image 933
Sunny Avatar asked Apr 17 '10 17:04

Sunny


People also ask

Can we have NULL values in map?

Values entered in a map can be null .


2 Answers

In C++11 you can do this:

auto it = min_element(pairs.begin(), pairs.end(),                       [](decltype(pairs)::value_type& l, decltype(pairs)::value_type& r) -> bool { return l.second < r.second; }); 

Or put it in a nice function like this (note I'm not a template guru; this is probably wrong in many ways):

template<typename T> typename T::iterator min_map_element(T& m) {     return min_element(m.begin(), m.end(), [](typename T::value_type& l, typename T::value_type& r) -> bool { return l.second < r.second; }); } 

With C++14, it further simplifies to:

min_element(pairs.begin(), pairs.end(),             [](const auto& l, const auto& r) { return l.second < r.second; }); 
like image 130
Timmmm Avatar answered Oct 20 '22 03:10

Timmmm


You have a few options. The "best" way to do this is with a functor, this is guaranteed to be the fastest to call:

typedef std::pair<std::string, int> MyPairType; struct CompareSecond {     bool operator()(const MyPairType& left, const MyPairType& right) const     {         return left.second < right.second;     } };    int MyClass::getMin(std::map<std::string, int> mymap)  {   std::pair<std::string, int> min        = *min_element(mymap.begin(), mymap.end(), CompareSecond());   return min.second;  } 

(You can also nest the CompareSecond class inside MyClass.

With the code you have now, you can easily modify it to work, however. Just make the function static and use the correct syntax:

static bool  MyClass::compare(std::pair<std::string, int> i, std::pair<std::string, int> j)  {    return i.second < j.second;  }  int MyClass::getMin(std::map<std::string, int> mymap)  {   std::pair<std::string, int> min = *min_element(mymap.begin(), mymap.end(),                                                   &MyClass::compare);   return min.second;  } 
like image 21
rlbond Avatar answered Oct 20 '22 02:10

rlbond