Reputation: 14950
Is there a simpler and better way to solve this problem because
if else
statements Write a program that receives three integers as input and outputs the numbers in increasing order.
Do not use loop / array.
#include <stdio.h>
main(){
int no1;
int no2;
int no3;
int sto;
int hi;
int lo;
printf("Enter No. 1: ");
scanf("%d", &no1);
printf("Enter No. 2: ");
scanf("%d", &no2);
printf("Enter No. 3: ");
scanf("%d", &no3);
if (no1>no2) {
sto=no1;
lo=no2;
} else {
sto=no2;
lo=no1;
}
if (sto>no3) {
hi=sto;
if(lo>no3){
sto=lo;
lo=no3;
}else {
sto=no3;
}
}else hi=no3;
printf("LOWEST %d\n", lo);
printf("MIDDLE %d\n", sto);
printf("HIGHEST %d\n", hi);
getch();
}
Upvotes: 25
Views: 134678
Reputation: 12769
In one of his talks1, Walter E. Brown discussed the usage of operator less in many algorithms, also "showing how easy it is to make mistakes when using operator < primitive directly". That was a C++ talk, specifically about the C++ Standard Library, but one the algorithms he showed was precisely a three items sort.
Written in C, the functions he propesed would look like this:
#include <stdbool.h>
bool out_of_order(int a, int b) {
return b < a;
}
bool in_order(int a, int b) {
return !out_of_order(a, b);
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void sort2(int *a ,int *b) {
if ( out_of_order(*a, *b) )
swap(a, b);
}
void sort3(int *a, int *b, int *c) {
sort2(a, b);
if ( in_order(*b, *c) )
return; // <-- Note the early returns
swap(b, c);
if ( in_order(*a, *b) )
return; // <--
swap(a, b);
}
He also mentioned that this is actually a (maybe unfamiliar) implementation of bubble sort2.
If you are scared by the multiple function calls, please look at the assembly generated by GCC, compiling with -O2
:
sort3:
mov eax, DWORD PTR [rsi]
mov ecx, DWORD PTR [rdi]
cmp eax, ecx
jge .L8
mov DWORD PTR [rdi], eax
mov eax, ecx
mov DWORD PTR [rsi], ecx
.L8:
mov ecx, DWORD PTR [rdx]
cmp ecx, eax
jge .L7
mov DWORD PTR [rsi], ecx
mov DWORD PTR [rdx], eax
mov edx, DWORD PTR [rsi]
mov eax, DWORD PTR [rdi]
cmp edx, eax
jge .L7
mov DWORD PTR [rdi], edx
mov DWORD PTR [rsi], eax
.L7:
ret
Compare it with the one generated by the code3 in the accepted answer:
sort_three:
mov eax, DWORD PTR [rdi]
mov ecx, DWORD PTR [rdx]
cmp eax, ecx
jle .L13
mov DWORD PTR [rdi], ecx
mov DWORD PTR [rdx], eax
mov eax, DWORD PTR [rdi]
.L13:
mov ecx, DWORD PTR [rsi]
cmp ecx, eax
jge .L14
mov DWORD PTR [rdi], ecx
mov ecx, eax
mov DWORD PTR [rsi], eax
.L14:
mov eax, DWORD PTR [rdx]
cmp eax, ecx
jge .L12
mov DWORD PTR [rsi], eax
mov DWORD PTR [rdx], ecx
.L12:
ret
Can you spot the differences?
1) There are multiple versions of it:
Correctly Calculating min, max, and More - Walter E Brown - CPPP 2021
Walter E. Brown - Correctly calculating min, max and more - Meeting C++ online
itCppCon21 - Extrema: Correctly Calculating min and max (Walter E Brown)
2) https://en.wikipedia.org/wiki/Bubble_sort
3) Well, slighlty modified, I had to make those variables pointers: https://godbolt.org/z/9Yn8xEM68
Upvotes: 0
Reputation: 37
This can be a solution if you are looking to sort only 3 numbers.
void orderOfThree(int *a1, int *a2, int *a3){
if (*a1 > *a2){ // 6 4 3
int temp_number = *a1;
*a1 = *a2;
*a2 = temp_number;
}
if (*a2 > *a3){ // 4 3 6
int temp_number = *a2;
*a2 = *a3;
*a3 = temp_number;
}
if (*a1 > *a2){ // 3 4 6
int temp_number = *a1;
*a1 = *a2;
*a2 = temp_number;
}
}
Feel free to change * pointer arguments with your desired inputs.
Upvotes: 0
Reputation: 707
The following code performs only 2 (best case) to 3 (worst case) conditional tests, with no assignment operations nor any extra variables:
void from(int ref, int x, int y) {
(ref < y) ? ((x < y) ? echo(ref,x,y) : echo(ref,y,x)) : echo(y,ref,x);
}
void printSorted(int a, int b, int c) { (a < b) ? from(a,b,c) : from(b,a,c); }
Basic call (scanf()
stuff avoided for simplicity):
void echo(int _1st, int _2nd, int _3rd) { printf("%d %d %d", _1st, _2nd, _3rd); }
int main() {
printSorted(2,3,1); //Output: 1 2 3
}
Upvotes: 1
Reputation: 1
int number1 = int.Parse(Console.ReadLine());
int number2 = int.Parse(Console.ReadLine());
int number3 = int.Parse(Console.ReadLine());
int swap = 0;
if (number2 > number1 && number2 > number3)
{
swap = number2;
number2 = number1;
number1 = swap;
}
else if (number3 > number2 && number3 > number1)
{
swap = number3;
number3 = number1;
number1 = swap;
}
if (number3 > number2)
{
swap = number2;
number2 = number3;
number3 = swap;
}
Console.WriteLine(number1 + "/" + number2 + "/" + number3);
Console.ReadKey();
Upvotes: -2
Reputation: 1
#include <stdio.h>
int main() {
int a,b,c;
printf("enter a b c values:\n");
scanf("%d%d%d",&a,&b,&c);
if(a<b && a<c)
{ printf("%d,",a);
if(b<c)
printf("%d,%d",b,c);
else
printf("%d,%d",c,b);
}
else if(b<a && b<c)
{
printf("%d,",b);
if(a<c)
printf("%d,%d",a,c);
else
printf("%d,%d",c,a);
}
else
{
printf("%d,",c);
if(a<b)
printf("%d,%d",a,b);
else
printf("%d,%d",b,a);
}
return 0;
}
Upvotes: -1
Reputation: 21
#include <stdio.h>
int main()
{
int a;
int b;
int c;
//Temporary storage variable
int t = 0;
printf("Enter No. a: ");
scanf("%d", &a);
printf("Enter No. b: ");
scanf("%d", &b);
printf("Enter No. c: ");
scanf("%d", &c);
if (a > b)
{
t = a;
a = b;
b = t;
}
if (a > c)
{
t = a;
a = c;
c = t;
}
if (c < b)
{
t = c;
c = b;
b = t;
}
printf("a = %d < b = %d < c = %d", a, b, c);
return 0;
}
Upvotes: 2
Reputation: 84569
To find the min, mid and max of 3 values, you can use the ternary operator. You can either do all your work within the main body of your code, or you can separate the minof3
, midof3
and maxof3
calculations into reusable functions.
In the case of min and max you simply make 2 out of 3 possible comparisons, and then return a comparison of the results. In the case of mid, you do the same, but compute the min and max of the 3 values, and then check all 3 against min and max in order to find the value that is neither the min or max. (you can do this part in the main body of your code without an additional function by declaring the min and max values as variables and doing the elimination there).
Putting the pieces together, you could do something similar to the following, which takes the first 3 arguments as the values to sort (or uses defaults of 99, 231, 8
if a needed value isn't specified)
#include <stdio.h>
#include <stdlib.h>
/** direct ternary comparison of 3 values */
long minof3 (long a, long b, long c) {
long x = a < b ? a : b,
y = a < c ? a : c;
return x < y ? x : y;
}
long maxof3 (long a, long b, long c) {
long x = a > b ? a : b,
y = a > c ? a : c;
return x > y ? x : y;
}
long midof3 (long a, long b, long c) {
long x = a < b ? a : b,
y = a > b ? a : b,
z = y < c ? y : c;
return x > z ? x : z;
}
int main (int argc, char **argv) {
long x = argc > 1 ? strtol (argv[1], NULL, 10) : 99,
y = argc > 2 ? strtol (argv[2], NULL, 10) : 231,
z = argc > 3 ? strtol (argv[3], NULL, 10) : 8;
/* strtol validations omitted for brevity */
printf ("\n sorted values : %ld, %ld, %ld\n",
minof3 (x, y, z), midof3 (x, y, z), maxof3 (x, y, z));
}
Example Use/Output
$ ./bin/sort3
sorted values : 8, 99, 231
$ ./bin/sort3 -23 -281 1031
sorted values : -281, -23, 1031
(yes, I know this is an old post, but given the recent comment about code hidden behind the swap
function, a full example was in order).
Upvotes: 1
Reputation: 41872
A compact solution sans magic swap()
function, that dances around int
overflow, and abuses arrays:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int a = atoi(argv[1]);
int b = atoi(argv[2]);
int c = atoi(argv[3]);
int ab[] = {a, b}, bc[] = {b, c};
int smaller[] = {ab[a > b], bc[b > c]}, larger[] = {ab[a < b], bc[b < c]};
int smallest = smaller[a > c], largest = larger[a < c];
int middle = (a - smallest) + (b - largest) + c;
printf("%d, %d, %d\n", smallest, middle, largest);
return 0;
}
USAGE
> ./a.out 2147483647 2147483645 2147483646
2147483645, 2147483646, 2147483647
>
Upvotes: 0
Reputation: 47373
if (a > c)
swap(a, c);
if (a > b)
swap(a, b);
//Now the smallest element is the 1st one. Just check the 2nd and 3rd
if (b > c)
swap(b, c);
Note: Swap changes the values of two variables.
Upvotes: 33
Reputation: 694
I was attempting to solve the same problem today. Could make this compact version of code without using any temporary variables; loops; library functions like swap, sort, max, min, etc. The code uses only if statements and makes continuous mutations in the hierarchy until all possibilities are checked.
int main()
{
int a, b, c; //User inputs stored in these three variables
int first, second, third; //These three variables will store the sorted numbers in sequence
std::cout<<"Please enter three integers : "; //User input prompt
std::cin>>a>>b>>c;
first = a; //Initially assuming number 'a' is smallest
if (b <= a && b <= c) first = b; //Checking whether b is smallest
if (c <= a && c <= b) first = c; //Checking whether c is smallest
if (((a >= b && a <= c) || (a >= c && a <= b))) second = a; //Checking if a is middle number
if (((b >= a && b <= c) || (b >= c && b <= a))) second = b; //Checking if b is middle number
if (((c >= a && c <= b) || (c >= b && b <= a))) second = c; //Checking if c is middle number
if (a >= b && a >= c) third = a; //Checking if a is the greatest
if (b >= c && b >= a) third = b; //Checking if b is the greatest
if (c >= a && c >= b) third = c; //Checking if c is the greatest
std::cout<<"The numbers in ascending order are : "<<first<<", "<<second<<", "<<third<<std::endl;
}
Upvotes: -3
Reputation: 4380
If you want to sort the values into new external variables, you can actually do the swaps without temporaries:
void sort(int a, int b, int c, int *min, int *mid, int *max) {
min = a;
mid = b;
max = c;
if (min > mid) { mid = a; min = b; }
if (mid > max)
{
max = mid;
mid = c;
if (min > mid)
{
mid = min;
min = c;
}
}
}
This works because the last swap test is really only needed if the second test succeeds (otherwise it will simply be a repetition of the first test, which will fail by definition since we already sorted those variables).
Because of this, we can track the assignments of each of the original variables and avoid swap locals.
Upvotes: 7
Reputation: 3898
#include <stdio.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
int main(){
int a, b, c;
int hi;
int lo;
printf("Enter No. 1: ");
scanf("%d", &a);
printf("Enter No. 2: ");
scanf("%d", &b);
printf("Enter No. 3: ");
scanf("%d", &c);
lo = min(min(a, b), c);
hi = max(max(a, b), c);
printf("LOWEST %d\n", lo);
printf("MIDDLE %d\n", a+b+c-lo-hi);
printf("HIGHEST %d\n", hi);
getchar();
}
Upvotes: 10
Reputation: 500465
Call the three variables x
, y
, and z
, then:
if (x > y) swap(x, y);
if (y > z) swap(y, z)
if (x > y) swap(x, y);
Writing the swap
function is left as an exercise for the reader. Hint: you may have to use pointers.
Upvotes: 11