对三个数字进行排序的更简单方法
Posted
技术标签:
【中文标题】对三个数字进行排序的更简单方法【英文标题】:Simpler way of sorting three numbers 【发布时间】:2010-12-06 15:07:45 【问题描述】:有没有更简单更好的方法来解决这个问题,因为
-
我使用了太多变量。
我用了这么多
if else
语句
我使用蛮力方法做到了这一点
编写一个程序,接收三个整数作为输入,并按升序输出这些数字。 不要使用循环/数组。
#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();
【问题讨论】:
相关帖子 - Sorting 3 numbers without branching 【参考方案1】: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);
注意:交换改变两个的值 变量。
【讨论】:
如果你将一半的代码隐藏在swap()
函数后面并假装它只有 3 行代码;为什么不将所有内容隐藏在 sort3()
函数中并假装它只有一行?如果你展示swap()
功能,那么至少OP有机会实现原始代码(没有swap()
)优越(性能)。
更不用说这甚至不起作用。变量 a、b 和 c 是按值传递的……(除非 swap 是一个宏,在那种情况下,哦男孩)【参考方案2】:
调用x
、y
、z
这三个变量,则:
if (x > y) swap(x, y);
if (y > z) swap(y, z)
if (x > y) swap(x, y);
编写swap
函数留给读者作为练习。提示:您可能必须使用指针。
【讨论】:
【参考方案3】:#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();
【讨论】:
数学上 a+b+c-lo-hi 是正确的,但计算上它可能会给我们带来溢出。所以swap版本更安全。 为什么使用宏而不是常规函数? Jarod42,为什么不呢?【参考方案4】:提示:如果你有 3 个数字,a、b 和 c,min(a, min(b, c)) 是最小的,max(a, max(b, c)) 是最大的,并且给定最小和最大的数字,应该很容易找到第三个。
【讨论】:
【参考方案5】:如果要将值排序到新的外部变量中,实际上可以在没有临时变量的情况下进行交换:
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;
这是可行的,因为实际上只有在第二次测试成功时才需要最后一次交换测试(否则它将只是第一次测试的重复,因为我们已经对这些变量进行了排序,所以根据定义它会失败)。
因此,我们可以跟踪每个原始变量的分配并避免交换局部变量。
【讨论】:
【参考方案6】:这是一个紧凑且无分支的 Julia 版本。
function sort_asc(a, b, c)
l1, h1 = minmax(a, b)
lo, h2 = minmax(l1, c)
md, hi = minmax(h1, h2)
return lo, md, hi
end
【讨论】:
这太棒了!并且直接翻译成向量化的 C++,现在 min/max 指令非常快(Zen3 每个时钟可以运行 2 个浮点 min/max 指令,每个时钟可以运行 4 个整数 min/max 指令),这段代码总共只需要 6 个.【参考方案7】:是的,有一个更好的方法,但是你需要使用循环和数组。
对于入门课程,您的答案可能就是他们正在寻找的答案。
有一些方法可以使用 for/while(递归、goto 等)进行循环。以及在没有索引的情况下获得类似数组的方法(int *ptr = malloc (3 * sizeof(int))
,然后使用*(ptr+index)
进行索引)。但是,我很难想象这就是他们想要的。
【讨论】:
这个问题可能不值得——我认为你的答案与其他人建议的一些修改(例如交换)是你的老师正在寻找的。我的建议是如何在没有循环或数组的情况下获得循环和数组行为,但这有点不符合你老师提出的问题的精神(我认为)【参考方案8】:以下代码仅执行 2(最佳情况)到 3(最坏情况)条件测试,没有赋值操作,也没有任何额外变量:
void echo(int _1st, int _2nd, int _3rd) printf("%d %d %d", _1st, _2nd, _3rd);
void echoFrom(int pivot, int x, int y)
(pivot < y) ? ((x < y) ? echo(pivot, x, y) : echo(pivot, y, x)) : echo(y, pivot, x);
void printSorted(int a, int b, int c) (a < b) ? echoFrom(a, b, c) : echoFrom(b, a, c);
基本调用(为简单起见,避免使用scanf()
):
int main()
printSorted(2,3,1); //Output: 1 2 3
【讨论】:
【参考方案9】:要找到 min、mid 和 max 的 3 个值,可以使用 ternary 运算符。您可以在代码主体中完成所有工作,也可以将 minof3
、midof3
和 maxof3
计算分离为可重用的函数。
在 min 和 max 的情况下,您只需进行 3 次可能的比较中的 2 次,然后返回结果比较。在 mid 的情况下,您执行相同的操作,但计算 3 个值的最小值和最大值,然后将所有 3 个值与 min 和 max em> 以便找到既不是 min 也不是 max 的值。 (通过将最小值和最大值声明为变量并在那里进行消除,您可以在代码的主体中执行此部分,而无需额外的功能)。
将这些部分放在一起,您可以执行类似于以下的操作,它将前 3 个参数作为要排序的值(如果未指定所需值,则使用默认值 99, 231, 8
)
#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));
使用/输出示例
$ ./bin/sort3
sorted values : 8, 99, 231
$ ./bin/sort3 -23 -281 1031
sorted values : -281, -23, 1031
(是的,我知道这是一篇旧帖子,但鉴于最近关于隐藏在 swap
函数后面的代码的评论,一个完整的例子是有序的)。
【讨论】:
【参考方案10】:一个没有魔法 swap()
函数的紧凑解决方案,它围绕int
溢出跳舞,并滥用数组:
#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;
用法
> ./a.out 2147483647 2147483645 2147483646
2147483645, 2147483646, 2147483647
>
【讨论】:
【参考方案11】:#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;
【讨论】:
虽然此代码可能会为问题提供解决方案,但最好添加有关其工作原理/方式的上下文。这可以帮助未来的用户学习并将这些知识应用到他们自己的代码中。在解释代码时,您也可能会以赞成票的形式从用户那里获得积极的反馈。【参考方案12】:#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;
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案13】:如果我们寻找最少比较次数作为对 3 个元素进行排序的最有效解决方案,请遵循以下实现
public static void Sort3Elements(int a, int b, int c)
if (a <= b && a <= c) //a is lowest here
if (b<=c) //a <= b <= c
Console.WriteLine("0-1-2", a, b, c);
else //a <= c <= b
Console.WriteLine("0-1-2", a, c, b);
else if (b<=a && b<=c) //b is lowest here
if (a <= c) //b <= a <= c
Console.WriteLine("0-1-2", b, a, c);
else //b <= c <= a
Console.WriteLine("0-1-2", b, c, a);
else //c is lowest
if (a <= b) //c <= a <= b
Console.WriteLine("0-1-2", c, a, b);
else //c <= b <= a
Console.WriteLine("0-1-2", c, b, a);
【讨论】:
这个答案完全依赖于外部链接的内容。如果它们变得无效,您的答案将毫无用处。所以请edit你的答案,并至少添加一个可以在那里找到的摘要。谢谢! 有道理,我会尽快发布答案。 只是一个问题,Console.WriteLine
是 C 的一部分吗?
这是一个示例 C# 代码,用于在控制台中显示已排序的输出。您可以将数据推送到数组或您喜欢的位置以进行进一步计算。
3 到 5 次比较不是最少可能的,并且该问题已明确标记为 c。【参考方案14】:
我今天试图解决同样的问题。可以在不使用任何临时变量的情况下制作这个紧凑版本的代码;循环;库函数,如 swap、sort、max、min 等。代码仅使用 if 语句,并在层次结构中进行连续突变,直到检查所有可能性。
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;
【讨论】:
这很酷,但很难说它比 OPs 版本“更紧凑”。 (我是否缺少讽刺意味?)以上是关于对三个数字进行排序的更简单方法的主要内容,如果未能解决你的问题,请参考以下文章