hunterge
hunterge

Reputation: 653

C++ finding the (largest) index of the largest element in an array

I have an array of values and a technique for finding the index of the largest element in an array.

value = distance(arrayOfValues, max_element(arrayOfValues, arrayOfValues + N));

However if there's multiple instances of the largest value, for e.g. {3,1,3,4,4,3,2} it only returns the smallest index (in this case 3), whereas I'd like it to return the largest index, in this case 4.

The only way I can think of doing it would be to create a new array which is identical to 'arrayOfValues' but in reverse, and then apply the above method.

Is there a simpler way of doing it that would avoid creating a new array? Perhaps by manipulating the above piece of code?

Upvotes: 1

Views: 4242

Answers (4)

Scott
Scott

Reputation: 1222

In a for loop add an if statement. Something like...

int indexToReturn = 0;
int indexValue = 0;
int newValue = 0;
for (int i = 0; i < arrayCount; i++) {
    newValue = arrayOfValues[i];
    if (newValue >= indexValue) {
        indexToReturn = i;
        indexValue = newValue;
    }
// At the end of this loop the value you want is indexToReturn
}

Upvotes: 2

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275330

Use reverse iterators into your range.

You pass end to the reverse iterator constructor to get the reverse begin, and begin to get the reverse end.

template<class It>
std::reverse_iterator<It> rit(It i){return {i};}

template<class C>
struct backwards_t {
  C c;
  auto end() {
    using std::begin;
    return rit(begin(c));
  }
  auto begin() {
    using std::end;
    return rit(end(c));
  }
};
template<class C>
backwards_t<C> backwards(C&&c){return {std::forward<C>(c)};}

is a C++14 way to do it.

auto yarra = backwards(array);
auto it = std::max_element(yarra.begin(), yarra.end());

this also lets you call backwards in a for(:) loop and iterate backwards.

Upvotes: 3

Jarod42
Jarod42

Reputation: 217135

You may provide a custom comparer to also compare address:

const int index =
    std::distance(std::begin(arrayOfValues),
        std::max_element(std::begin(arrayOfValues), std::end(arrayOfValues),
        [](const int& lhs, const int& rhs) {
            return std::make_tuple(lhs, &lhs)
            < std::make_tuple(rhs, &rhs);
        }
        ));

Live example

Upvotes: 3

fkdosilovic
fkdosilovic

Reputation: 116

You probably have something like this:

int maxIdx = 0;  
for(int i = 0; i < n; ++i)
  if(a[maxIdx] > a[i])
    maxIdx = i;

return maxIdx;

You just need to add one character to if statement:

if(a[maxIdx] >= a[i])
  maxIdx = i;

Upvotes: 2

Related Questions