Uses GCC-specific argument-argument-macro-variables-variables for testing, but in any case the main ideas:
If len is less than 2 (I think we can return a special value like 0 or MinInt.)
- Here I return a NULL pointer, not a pointer safe for markup, so there is no problem with having 0 or MinInt in the data.
But if the second largest is 0. (Since in this case I cannot distinguish between the error and the normal return value, so I could make an exception)
The exception to reasonable input is pretty seriously bad!
If the array is {1,1,1} (since 1 is the largest number and not the second largest, so I can throw an exception)
This can be argued, but this is the behavior that I modeled, also returning NULL.
So:
- distinguish a condition from an unreasonable condition using pointers against NULL
- the second highest value can be maintained by tracking the largest when we repeat once
The code is a bit choppy, but FWIW:
#include <iostream> template <typename T, int N> T* second_largest(T (&arr)[N]) { if (N < 2) return NULL; T* largest = &arr[0]; T* second = NULL; for (int i = 1; i < N; ++i) { if (arr[i] > *largest) { second = largest; largest = &arr[i]; } else if (arr[i] != *largest && (!second || arr[i] > *second)) second = &arr[i]; std::cout << "i " << i << ", largest " << (largest ? *largest : -1) << ", second " << (second ? *second : -1) << '\n'; } return second; }
source share