-2

I want to find the greatest and second greatest out of 3 numbers A, B, and C.

For greatest I know I can use the max() function like such: max(a,max(b,c)); How would you find the second greatest?

1110101001
  • 4,662
  • 7
  • 26
  • 48
  • I have managed to do it by using 3 if statements and based on what the value of max(a,max(b,c)) is, the second greatest is the max of the other two. Is there anything more elegant than using 3 if statements? – 1110101001 Oct 24 '13 at 02:00
  • 1
    So do you want a solution or do you want to know if there is a better solution than yours? You need a specific question to get answers, and questions of the type "how can I make this code better" will probably result in a closed question. – vanza Oct 24 '13 at 02:01
  • Why don't you just find the smallest and assume that the two that aren't the greatest are the greatest two? – nhgrif Oct 24 '13 at 02:02
  • 1
    Perhaps it would help to finish (or start) vanza's comment with *"Show us"* – WhozCraig Oct 24 '13 at 02:02
  • 1
    For clarity, he seems to want a solution. What he's got so far will only find the largest ONE of three. He is stuck on how to figure out which number is the second largest. – nhgrif Oct 24 '13 at 02:03
  • Why not just do it with branched ifs for every combination, in the end it still has less overhead than any other answer. See here: http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/sort.html – aeroson Feb 14 '16 at 15:18

3 Answers3

2

The simplest solution in my opinion, but perhaps a bit overkill, is to just put them in an array or a vector and sort.

This way, you can access anything you're looking for, and it would be easy to add more numbers into the mix. You also wouldn't have to keep track of all your if's.

#include <iostream>
#include <algorithm>

using namespace std;

int main(){
    static const int size = 3;

    int arr[size] = { 3, 1, 2 };

    sort(arr, arr+size);

    cout << "Lowest: " << arr[0] << endl; // Prints out 1
    cout << "Middle: " << arr[1] << endl; // Prints out 2
    cout << "Highest: " << arr[2];        // Prints out 3

    return 0;
}

Alternatively, you can loop through the array yourself and look for the second greatest number using an O(n) loop which is way more efficient than sorting.

Here's a function you can use to get the second greatest number from an array (interpreted from this answer)

#include <iostream>
#include <limits>

#define int_min numeric_limits<int>::min()

using namespace std;

int SecondGreatest(int arr[], int count){
    int largest = int_min, 
        second = int_min;

    for(int i = 0; i < count; i++){
        if(arr[i] > largest){
            second = largest;
            largest = arr[i];
        }else if(arr[i] > second){
            second = arr[i];
        }
    }

    return second;
}

int main(){
    static const int size = 4;
    int arr[size] = { 6, 5, 8, 10 };

   cout << "Second largest: " << SecondGreatest(arr, size); //Prints out 8

   return 0;
}

Here's a reference.

Community
  • 1
  • 1
ShadowScripter
  • 7,314
  • 4
  • 36
  • 54
2

The algorithm will look like:

    greatest = std::max(a, secondGreatest = std::max(b, c));
    secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest);

here's working listing for most combinations in asserts:

#include <iostream>
#include <cassert>

int main()
{
    int a = 5, b = 10, c = 15;
    int greatest = 0, secondGreatest = 0;

    greatest = std::max(a, secondGreatest = std::max(b, c));
    assert(secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest) == 10);

    a = 10, b = 5, c = 15;
    greatest = std::max(a, secondGreatest = std::max(b, c));
    assert(secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest) == 10);

    a = 15, b = 5, c = 10;
    greatest = std::max(a, secondGreatest = std::max(b, c));
    assert(secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest) == 10);

    a = 15, b = 10, c = 5;
    greatest = std::max(a, secondGreatest = std::max(b, c));
    assert(secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest) == 10);

    a = 5, b = 15, c = 10;
    greatest = std::max(a, secondGreatest = std::max(b, c));
    assert(secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest) == 10);

    a = 10, b = 15, c = 5;
    greatest = std::max(a, secondGreatest = std::max(b, c));
    assert(secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest) == 10);

    a = 15, b = 5, c = 5;
    greatest = std::max(a, secondGreatest = std::max(b, c));
    assert(secondGreatest = std::min(std::max(std::min(b, c), a), secondGreatest) == 5);

    return 0;
}
Iuri Covalisin
  • 645
  • 4
  • 7
1

If you don't need the order between the greatest two, then finding the greatest and second greatest is not necessary. We only need to find the least of three to know which two are the greatest. And this can be done by using generic algorithm of finding the least and removing it .

std::list<int> numbers(...) // put three your numbers here.
std::list<int>::iterator min = std::min_element(std::begin(v), std::end(v));
numbers.erase(min);

Then you have your two numbers in numbers.

If you need the order, then just sort it.

WiSaGaN
  • 46,887
  • 10
  • 54
  • 88