Francis Cugler
Francis Cugler

Reputation: 7905

C++ retrieving an index value in a vector while using min_element or max_element

I'm working on a problem here where I have two vector objects in my code: one is a vector<string>, and the other a vector<unsigned> that I'm passing as a const ref to some function. I'm using these functions to find the minimum or maximum value out of one vector, but I need the index value of the minimum or maximum so that I can index into the other vector. My code looks something like this:

std::string getTopEmployee( const std::vector<std::string>& names, const std::vector<unsigned>& ratings ) {
    // Find Largest Value in ratings
    std::size_t largest = *std::max_element( ratings.begin(), ratings.end() );
    // How to get the index?
    // I do not need the largest value itself.

    return names[index];
}

std::string getWorstEmployee( const std::vector<std::string>& names, const std::vector<unsigned>& ratings ) {

   // Find Smallest Value in ratings
   std::size_t smallest = *std::min_element( ratings.begin(), ratings.end() );
    // How to get the index?
    // I do not need the smallest value itself.

    return names[index];
}

The two vectors passed into this function are of the same size: and we are assuming that there are no two values in the ratings vector that are equal in value. Sorting the second vector is not an option.

Upvotes: 8

Views: 14361

Answers (2)

DAle
DAle

Reputation: 9117

For std::vector or any other container with random-access iterators you can use arithmetic operators (let's assume for simplicity that containers are not empty):

 auto maxi = std::max_element(ratings.begin(), ratings.end());
 return names[maxi - ratings.begin()];

Complexity: O(1).

For containers with iterators that are at least input iterators, you can use std::distance:

 auto maxi = std::max_element(ratings.begin(), ratings.end());
 return names[std::distance(ratings.begin(), maxi)];

Complexity: O(1) with random-access iterators, O(n) with not random-access.

Upvotes: 8

Remy Lebeau
Remy Lebeau

Reputation: 596156

std::min_element() and std::max_element() work with iterators, not indexes.

For an indexable container like std::vector, you can convert an iterator to an index using std::distance(), eg:

std::string getTopEmployee( const std::vector<std::string>& names, const std::vector<unsigned>& ratings ) {
    // Find Largest Value in ratings
    auto largest = std::max_element( ratings.begin(), ratings.end() );
    if (largest == ratings.end()) return "";
    return names[std::distance(ratings.begin(), largest)];
}

std::string getWorstEmployee( const std::vector<std::string>& names, const std::vector<unsigned>& ratings ) {
    // Find Smallest Value in ratings
    auto smallest = std::min_element( ratings.begin(), ratings.end() );
    if (smallest == ratings.end()) return "";
    return names[std::distance(ratings.begin(), smallest)];
}

Upvotes: 17

Related Questions