对三个数字进行排序的更简单方法

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】:

调用xyz这三个变量,则:

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】:

要找到 minmidmax 的 3 个值,可以使用 ternary 运算符。您可以在代码主体中完成所有工作,也可以将 minof3midof3maxof3 计算分离为可重用的函数。

minmax 的情况下,您只需进行 3 次可能的比较中的 2 次,然后返回结果比较。在 mid 的情况下,您执行相同的操作,但计算 3 个值的最小值和最大值,然后将所有 3 个值与 minmax 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 版本“更紧凑”。 (我是否缺少讽刺意味?)

以上是关于对三个数字进行排序的更简单方法的主要内容,如果未能解决你的问题,请参考以下文章

在Clojure中对地图矢量进行排序和排序的更清洁方法?

在Javascript中对地址数组进行排序[重复]

根据Java中的值对地图进行排序的最简单方法是啥?

数组排序相关

对数组进行部分排序 C

php 数组排序以及按照某个字段排序