【问题标题】:Simpler way of sorting three numbers对三个数字进行排序的更简单方法
【发布时间】:2010-12-06 15:07:45
【问题描述】:

有没有更简单更好的方法来解决这个问题,因为

  1. 我使用了太多变量。
  2. 我用了这么多if else语句
  3. 我使用蛮力方法做到了这一点

编写一个程序,接收三个整数作为输入,并按升序输出这些数字。
不要使用循环/数组。

#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(); 
}    

【问题讨论】:

标签: c


【解决方案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 版本“更紧凑”。 (我是否缺少讽刺意味?)
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-04-22
              • 1970-01-01
              • 2017-02-14
              • 2015-03-31
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多