Πώς μπορώ να βρω την ελάχιστη τιμή σε έναν χάρτη;

Πώς μπορώ να βρω την ελάχιστη τιμή σε έναν χάρτη;

Έχετε μερικές επιλογές. Ο "καλύτερος" τρόπος για να το κάνετε αυτό είναι με έναν συνάρτηση , αυτό είναι εγγυημένο ότι είναι το πιο γρήγορο για κλήση:

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; 
}

(Μπορείτε επίσης να τοποθετήσετε το CompareSecond τάξη μέσα στο MyClass .

Ωστόσο, με τον κωδικό που έχετε τώρα, μπορείτε εύκολα να τον τροποποιήσετε ώστε να λειτουργεί. Απλώς κάντε τη συνάρτηση static και χρησιμοποιήστε τη σωστή σύνταξη:

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; 
}

Στην C++11 μπορείτε να κάνετε το εξής:

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

Ή βάλτε το σε μια ωραία λειτουργία όπως αυτή (σημειώστε ότι δεν είμαι γκουρού προτύπων, αυτό είναι πιθανώς λάθος από πολλές απόψεις):

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; });
}

Με τη C++14, απλοποιεί περαιτέρω:

min_element(pairs.begin(), pairs.end(),
            [](const auto& l, const auto& r) { return l.second < r.second; });

Το πρόβλημα είναι ότι αυτό:

bool MyClass::compare

Απαιτεί ένα στιγμιότυπο της κλάσης που θα κληθεί. Δηλαδή, δεν μπορείτε απλώς να καλέσετε το MyClass::compare , αλλά χρειάζεστε someInstance.compare . Ωστόσο, min_element χρειάζεται το πρώτο.

Η εύκολη λύση είναι να το κάνετε static :

static bool MyClass::compare

// ...

min_element(mymap.begin(), mymap.end(), &MyClass::compare);

Αυτό δεν απαιτεί πλέον την κλήση μιας παρουσίας και ο κωδικός σας θα είναι εντάξει. Ωστόσο, μπορείτε να το κάνετε πιο γενικό με έναν συντελεστή:

struct compare2nd
{
    template <typename T>
    bool operator()(const T& pLhs, const T& pRhs)
    {
        return pLhs.second < pRhs.second;
    }
};

min_element(mymap.begin(), mymap.end(), compare2nd());

Το μόνο που κάνει είναι να αρπάξει το δεύτερο από κάθε ζευγάρι και να το αρπάξει, λειτουργεί με οποιοδήποτε ζευγάρι. Θα μπορούσε να γίνει για γενικά, αλλά αυτό είναι λίγο υπερβολικό.

Εάν πρέπει να αναζητήσετε αρκετή αξία, σας συνιστώ να χρησιμοποιήσετε το Bimap του Boost. Είναι ένας χάρτης αμφίδρομης κατεύθυνσης, επομένως τόσο το κλειδί όσο και η τιμή μπορούν να χρησιμοποιηθούν για αναζήτηση. Θα έχετε απλώς το μπροστινό μέρος του χάρτη τιμής-κλειδιού.

Τέλος, μπορείτε πάντα απλώς να παρακολουθείτε το ελάχιστο στοιχείο που εισέρχεται στον χάρτη σας. Κάθε φορά που εισάγετε μια νέα τιμή, ελέγχετε αν είναι χαμηλότερη από την τρέχουσα τιμή (και αυτή θα πρέπει να είναι μάλλον δείκτης σε ένα ζεύγος χάρτη, ξεκινήστε την ως μηδενική) και αν είναι χαμηλότερη, τοποθετήστε το δείκτη στο νέο χαμηλότερο. Το να ζητήσετε το χαμηλότερο γίνεται τόσο απλό όσο η αποσύνδεση ενός δείκτη.