Reputation: 7905
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
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
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