Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Beginner here, trying to make a small program that sorts three numbers from smallest to largest only by using ifs. Any thoughts on how to improve this?

#include <iostream>

using namespace std;
int main ()
{
    int num1, num2, num3;
    int smallest, middle, biggest;
    cin >> num1 >> num2 >> num3;

    cout << endl;

    if ((num1 < num2) && (num1 < num3))
    {
        smallest = num1;
        if (num2 > num3)
        {
            biggest = num2;
            middle = num3;
        }
    }
    if ((num1 < num2) && (num3 << num1))
    {
        smallest = num1;
        if (num2 < num3)
        {
            middle = num2;
            biggest = num3;
        }
    }
    if ((num1 > num2) && (num3 > num1))
    {
        middle = num1;
        if (num2 < num3)
        {
            smallest = num2;
            biggest = num3;
        }
    }
    if ((num1 < num2) && (num3 < num1))
    {
        middle = num1;
        if (num2 > num3)
        {
            biggest = num2;
            smallest = num3;
        }
    }
    if ((num1 > num2) && (num1 > num3))
    {
        biggest = num1;
        if (num3 > num2)
        {
            middle = num3;
            smallest = num2;
        }
    }

    if ((num1 > num2) && (num1 > num3))
    {
        biggest = num1;
        if (num2 > num3)
        {
            middle = num2;
            smallest = num3;
        }
    }

    cout << smallest << ", " << middle << ", " << biggest << endl;


    return 0;
}
share|improve this question
3  
Why the requirement of only using if? You might discover new things by trying other tools too :) –  Morwenn yesterday
1  
I still haven't reached that part of the book :) –  liquid3 yesterday
    
Also, it seems that your are using using namespace std; but it doesn't appear anywhere in your code. Could you edit your question to explicitly add it? Otherwise your code will not compile and will therefore be off-topic for Code Review. –  Morwenn yesterday
    
Yes this is edited, i have using namespace stdin the code, my bad –  liquid3 yesterday
    
Thank you, now your question is ready to be reviewed. Oh, and I forgot to mention it earlier, but welcome on Code Review :) –  Morwenn yesterday

5 Answers 5

up vote 8 down vote accepted

So, I will try to take many things into account but to keep it simple anyway. A few remarks:

  • First, it seems that you have a typo here:

    if ((num1 < num2) && (num3 << num1))
    

    I think that you meant num3 < num1 instead of num3 << num1 in your second condition.

  • As @Josay says, you better write small functions. I would add that you better separate the input/output operations (that you can keep in main) and the sorting function. In my opinion, this would be a good enough signature for such a function:

    void sort3(int& a, int& b, int& c);
    

    You would give three variables to it and it would sort them in-place so that you end up with \$ a \le b \le c \$.

  • Now, let's choose an algorithm. For three values, the easiest is to implement a bubble sort which shouldn't be slower than the other algorithms (when you want to sort more values, it becomes horribly slower).

    void sort3(int& a, int& b, int& c)
    {
        if (a > b)
        {
            std::swap(a, b);
        }
        if (b > c)
        {
            std::swap(b, c);
        }
        if (a > b)
        {
            std::swap(a, b);
        }
    }
    

    Most sorting algorithms heavily rely on swapping values. The one I just implemented sorts your values with only three comparisons and at most three swaps and is, in my opinion, far simpler to understand than what you had.

    Note that there are faster ways to do this but I deliberately chose to present one that is not so bad and easy to understand.

  • This is not a problem in your, but we can't stress out enough that using namespace std; is often considered bad practice. It is the case when used in a header file, especially in a library header file since it will pollute the global namespace of every file including it. That's not a problem for you since you're probably doing everything in a .cpp file but it's better to keep that in mind.

  • You don't need to return 0; at the end of main. If the compiler reaches the end of the main function without having encountered a return statement, it automagically adds a return 0; for you. Note that it only works with main though. Dropping this line is an interesting way to document that your program cannot return error codes and that it will only ever return 0.

share|improve this answer
    
Thanks for your answers, i'm afraid i can't give thumbs up because i need more rep –  liquid3 yesterday
    
+1. This should probably be the accepted answer. –  Josay yesterday
    
why did you test if a > b twice? –  Ritchie Shatter yesterday
1  
@RitchieShatter If the values are \$3, 2, 1\$ the first two swaps will make the values \$2, 1, 3\$ so you need to swap a and b again. –  Morwenn yesterday
1  
@RitchieShatter - don't know if this helps, but if you've studied how bubble sort works, think of this code as a bubble sort with the loops unrolled; the smallest values bubble down from the top. –  Pete Becker yesterday

A few pieces of advice:

  • write small functions you can test

  • write tests

I did it for you and discovered problems quickly :

#include <iostream>

using namespace std;

void sort(int num1, int num2, int num3, int* smallest, int* middle, int* biggest)
{
    if ((num1 < num2) && (num1 < num3))
    {
        *smallest = num1;
        if (num2 > num3)
        {
            *biggest = num2;
            *middle = num3;
        }
    }
    if ((num1 < num2) && (num3 << num1))
    {
        *smallest = num1;
        if (num2 < num3)
        {
            *middle = num2;
            *biggest = num3;
        }
    }
    if ((num1 > num2) && (num3 > num1))
    {
        *middle = num1;
        if (num2 < num3)
        {
            *smallest = num2;
            *biggest = num3;
        }
    }
    if ((num1 < num2) && (num3 < num1))
    {
        *middle = num1;
        if (num2 > num3)
        {
            *biggest = num2;
            *smallest = num3;
        }
    }
    if ((num1 > num2) && (num1 > num3))
    {
        *biggest = num1;
        if (num3 > num2)
        {
            *middle = num3;
            *smallest = num2;
        }
    }

    if ((num1 > num2) && (num1 > num3))
    {
        *biggest = num1;
        if (num2 > num3)
        {
            *middle = num2;
            *smallest = num3;
        }
    }


}

int main ()
{
    int num1, num2, num3;
    int smallest, middle, biggest;
    //cin >> num1 >> num2 >> num3;
    //sort(num1, num2, num3, &smallest, &middle, &biggest);
    //cout << endl;
    //cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 1; num2 = 2; num3 = 3;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 4; num2 = 4; num3 = 4;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 5; num2 = 5; num3 = 6;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 7; num2 = 8; num3 = 7;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 9; num2 = 10; num3 = 10;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 11; num2 = 13; num3 = 12;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 15; num2 = 14; num3 = 16;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 19; num2 = 18; num3 = 17;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 21; num2 = 22; num3 = 20;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    num1 = 25; num2 = 23; num3 = 24;
    sort(num1, num2, num3, &smallest, &middle, &biggest);
    cout << smallest << ", " << middle << ", " << biggest << endl;

    return 0;
}

gives :

1, 2, 3
1, 2, 3
1, 2, 3
7, 2, 3
9, 2, 3
11, 12, 13
14, 15, 16
17, 18, 19
20, 21, 22
23, 24, 25
share|improve this answer
    
Thanks for the answer, the problem is when i type 2 same numbers –  liquid3 yesterday

Your code compiles, but your program is not exactly small. I like what you are trying to do. When I learn something new, I like to write a program to help showcase it. The problem is you need to bring the correct tools for the job. Analogously You probably could hammer a nail with a screwdriver, but I wouldn't recommend it.

There are multiple ways you could get this code under 10 lines. use of "else" and "else if" may help. however you will make your life considerably easier using logical operators. For example

#define max(x,y) ( x > y ? x : y )

you can make a simple preprocessor command that will give you the maximum value.

The logic for that command would read as if x is greater than y the answer is x, otherwise it's y.

The swap command mentioned above would work well to. I highly recommend before limiting yourself to one statement you read a little about c++ operators. Try here.

http://www.cplusplus.com/doc/tutorial/operators/

share|improve this answer
    
You can get into some rather dangerous waters with that max macro if you do things such as max(foo + 1, bar). Code golf is great for people who understand the full set of tricks for the language, but code that is understandable to the coder(or next person) is often something to strive for. Clever code needs you to be more clever to debug it - and if the code is at your edge of cleverness this can cause problems. –  MichaelT yesterday
1  
Why define a max macro when there is already the safer std::max in the standard library? :( –  Morwenn yesterday
    
Interesting. I wasn't aware of std::max. nor std::swap. I guess I need to look through the std libraries at some point. MichaelT, your point is well taken. However, I still feel that a strong understanding of operators should be an early fundamental for learning c/c++ –  mreff555 yesterday

The answer @morwenn gave is nicely done. My answer is just incase you are currently unfamiliar with defining your own functions and using pre defined functions such a swap. It's based off of @morwenn's answer. I also would suggest adding a description of the program to the user.

#include <iostream>

int main()
{
    int num1 = 0;
    int num2 = 0;
    int num3 = 0;

    std::cout << "This program will sort three numbers in ascending order\n"
        << "Enter the first number: ";
   std::cin >> num1;
   std::cout << "Enter the second number: ";
   std::cin >> num2;
   std::cout << "Enter the third number: ";
   std::cin >> num3;

   int smallest = 0;
   int middle = 0;
   int biggest = 0;
   int temp = 0;

   if (num1 > num2)
   {
      temp = num1;
      num1 = num2;
      num2 = temp;
   }
   if (num2 > num3)
   {
      temp = num2;
      num2 = num3;
      num3 = temp;
   }
   if (num1 > num2)
   {
      temp = num1; 
      num1 = num2;
      num2 = temp;
   }

   smallest = num1;
   middle = num2;
   biggest = num3;

   std::cout << smallest << ", " << middle << ", " << biggest << std::endl;
}
share|improve this answer

Assuming you define min and max (or use std::min, std::max), you can do this:

int low, mid, high;
// Find the minimum of number 1 and the minimum of number 2 and number 3.
low = std::min(num1, std::min(num2, num3));
// Find the maximum of the minimum of number 1 and number 2 and the minimum of number 2 and number 3.
mid = std::max(std::min(num1, num2), std::min(num2, num3));
// Find the maximum of number 1 and the maximum of number 2 and number 3.
high = std::max(num1, std:max(num2, num3));

Which basically moves all of your if-else logic into standard library calls.

By the way, a popular method for switching numbers in place without a temporary integer goes as follows:

x = x ^ y;
y = y ^ x;
x = x ^ y;

Which replaces the need for a temp variable. Try it out and see.

if(a > b) {
    a = a ^ b;
    b = b ^ a;
    a = a ^ b;
}
if(b > c) {
    b = b ^ c;
    c = c ^ b;
    b = b ^ c;
}
if(a > b) {
    a = a ^ b;
    b = b ^ a;
    a = a ^ b;
}

Of course, you could instead use std::swap. However, given all the alternatives, if performance was a non-issue (e.g. absolute clock cycle count was unimportant), I'd impress simply using std::min and std::max.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.