【问题标题】:Biggest and smallest of four integers (No arrays, no functions, fewest 'if' statements)四个整数中的最大和最小(没有数组、没有函数、最少的“if”语句)
【发布时间】:2013-10-05 15:37:00
【问题描述】:

你看,我自学了 C++(不完全是,我还在拖延 -_-)。所以,现在我开始上大学,他们在教 C,他们让我们做一个输入四个整数的程序,我们必须说出其中最大和最小的。很简单,不是吗?

问题是,我已经对函数和数组有了很好的理解。是的,我可以在数组中编程,没问题。但由于这是第一个实验室,我们还没有“学习”到这一点,所以我不能使用其中的任何一个,这样会很简单。

这是我在那里写的(感觉有点不对劲)。

#include<stdio.h>

int main(void)
{
    int first, second, third, fourth;
    printf("Enter four integers (separated by space): ");
    scanf("%d %d %d %d", &first, &second, &third, &fourth);

    if((first>second) && (first>third) && (first>fourth))
        printf("\nFirst number is largest");
    else if((second>first) && (second>third) && (second>fourth))
        printf("\nSecond number is largest");
    else if((third>second) && (third>first) && (third>fourth))
        printf("\nThird number is largest");
    else if((fourth>second) && (fourth>third) && (fourth>first))
        printf("\nFourth number is largest");

    if((first<second) && (first<third) && (first<fourth))
        printf("\nFirst number is smallest");
    else if((second<first) && (second<third) && (second<fourth))
        printf("\nSecond number is smallest");
    else if((third<second) && (third<first) && (third<fourth))
        printf("\nThird number is smallest");
    else if((fourth<second) && (fourth<third) && (fourth<first))
        printf("\nFourth number is smallest");

    printf("\n"); 
    return 0;
}

如您所见,它太长、太无聊和太复杂了。但是看到我们现在在课堂上讨论的只是循环决策语句。有没有更优雅的方式来做到这一点? 使用较少的ifs?并不是说这有什么问题,但它可能会更好。

附:这不完全是“家庭作业”或任何东西。我做了一个程序,我只是想知道我可以做些什么来让它变得更好并学习更好的编程实践。

【问题讨论】:

  • 好吧,上面至少有一个问题:如果你输入相同的数字四次,它什么也不会打印。
  • 您需要实现部分 4 线 sorting network(是的,这只是嵌套 if 语句的花哨名称,但它显示了这些语句的最佳配置)。
  • @jon 即使任何两个相等...!
  • @Hamza Masud:要求同时找到最大和最小的问题的全部意义在于让您从每次比较中提取最大有价值的信息。例如,如果您知道a &gt; b 为真,那么从该单一比较中您应该意识到a 不再是最小的候选者,而b 不再是最大的候选者。基本上,有 4 个数字,两个测试 a &gt; bc &gt; d 已经清楚地将数字分成两个候选者最大和两个最小候选者。其余的都很简单。
  • if 用于选择数值的语句总是可以被位移操作(提取符号)和减法的适当组合替换;请参阅下面的答案。

标签: c


【解决方案1】:

根据 OP 的条件

但是看到我们现在在课堂上讨论的只是循环决策语句。有没有更优雅的方式来做到这一点? 使用较少的ifs

只有一个if 和一个else if 语句和一个for 循环可以执行此任务。 简单而简短!

#include <stdio.h>

int main()
{
    int num, max, min;

    printf ("Enter four numbers: ");
    scanf ("%d", &num);
    max = min = num;

    for (int i = 0; i < 3; i++)
    { 
        scanf ("%d", &num);
        if (max < num)
            max = num;
        else if (min > num)
            min = num;
    }

    printf ("The smallest and largest of given four numbers are %d and %d respectively.\n", min,  max);
    return 0;
}

【讨论】:

  • 哎呀,我不能指手画脚,但这比我试图想象的“for”循环方式要好得多。
【解决方案2】:

做一个“手动”merge sort,或者好吧,只是它的第二部分:

从概念上讲,合并排序的工作原理如下

  1. 将未排序的列表分成 n 个子列表,每个子列表包含 1 个元素(包含 1 个元素的列表被视为已排序)。
  2. 重复合并子列表以产生新的子列表,直到只剩下 1 个子列表。这将是排序列表。

代码:

int a = 5, b=4, c=7, d=9;
int min_ab, min_cd, min;
min_ab = a < b ? a : b;
min_cd = c < d ? c : d;
min = min_ab < min_cd ? min_ab : min_cd;
printf("%d", min);

.. 最大值也是如此。

如果您愿意,可以将三元运算符扩展为 if (a &lt; b) { min_ab = a; } else { min_ab = b; }(为了便于阅读,分散在多行中)。

归并排序的复杂度为O(n*log(n)),所以你最多应该需要O(n*log(n))ifs(见wikipedia article on merge sort)。根据维基百科,“......这些都是比较类型,因此在平均或最坏情况下不能比 O(n log n) 表现更好”(source),所以我认为这应该不会太远就ifs 的最小数量而言。虽然您可以尝试查看手动执行其他算法之一是否会导致更少的ifs ;-)。

【讨论】:

  • 有趣的是,我发布了基本相同的解决方案,只使用宏来表示最小值和最大值并得到 -3
  • 虽然我无法理解那些对你的答案投反对票的人(或那些对我的答案投赞成票的人)的想法,但我想这是因为 OP 明确表示“问题是,我已经很好理解函数和数组。是的,我可以在数组中编程,没问题。但由于这是第一个实验室,我们还没有“学习”到,所以我不能使用其中任何一个,它会非常就这么简单。” - 我猜宏与函数很接近,并且不属于预实验教学大纲的一部分。我也希望我回答中的理论和解释对读者有所帮助:)
  • 是的,所以我加了你
  • 很好,谢谢 - 我已经更新了代码,现在应该已经修复了。
【解决方案3】:

试试这样的

int main(void) {
    int a=-2,b=-3,c=-4,d=-5;
    int max=a,min=a;

    if(b>max){
        max=b;
    }else if(b<min){
        min=b;
    }
    if(c>max){
        max=c;
    }else if(c<min){
        min=c;
    }
    if(d>max){
        max=d;
    }else if(d<min){
        min=d;
    }
    printf("max: %d min : %d",max,min);
    return 0;
}

Demo

【讨论】:

  • int max = -INT_MIN。或者干脆int max = a
  • 太棒了!谢谢。每次我在 StackOverflow 上阅读答案时,我都会学到一些新东西。像这种“合并排序”,我知道如何使用它,但我从来不知道它叫什么。我希望有一天能成为你们中的一员!
  • @Arpit:可能。我不知道老师在这种情况下的意图是什么。但我几乎可以肯定,老师肯定希望看看一些学生是否会认识到问题的自然“层次”结构。这不是火箭科学,真的。
  • 我很高兴您也回答了这个问题,这是 SO 的专长,它允许我们以各种方式解决一个问题,技能从新手到专家都匹配。 :) 。你确实有更多的经验,所以你判断了老师的意图,但我是学生,所以我猜老师通常根据学生的意思。
  • 太多ifs 和else。此答案不符合 OP 的要求(尽管已被接受:))。
【解决方案4】:

要求同时找出最大和最小的课堂问题的重点是教你从每次比较中提取最大有价值的信息。

例如,如果您知道a &gt; b 为真,则从该单一比较中您应该意识到a 不再是最小的候选者,并且不应再参与任何专门用于查找最小的比较。同时,您应该意识到b 不再是最大的候选者。对于 4 个数字,a &gt; bc &gt; d 两个测试已经清楚地将数字分成两个独立的类别:最大的两个候选人和最小的两个候选人。其余的很简单。

换句话说,整个想法是并行找到极值,使用每次比较提供的信息来进一步找到最小和最大值。

if (first > second) { 
  int t = first; first = second; second = t; 
}

if (third > fourth) { 
  int t = third; third = fourth; fourth = t; 
}

/* Now 'first' and 'third' are candidates for the smallest,
   while 'second' and 'fourth' are candidates for the largest */

int min = first < third ? first : third;
int max = second > fourth ? second : fourth;

如您所见,只需进行四次比较即可找到这两个数字。

请注意,上面的代码为您提供了最小和最大的,但它没有告诉您提供每个值的数字的原始“索引”。目前尚不清楚是否真的有必要。您的问题文本对此一无所知,而您提供的代码示例实现了它。无论如何,更新上述代码以使其“追踪”数字的来源并不难。

【讨论】:

  • 这个真的没关系,只要输出最大最小的数就可以了。
  • @HamzaMasud;为什么不相关?
  • @Hamza Masud:到底什么是无关紧要的?
  • 不相关,我的意思是如果你想弄乱索引,那没关系。如果你不想,那也没关系。虽然我认为“无关紧要”听起来有点刺耳?对不起。 :(
【解决方案5】:

这太简单了,因为数字是 a,b,c,d:

#define min(a,b)  ((a) < (b) ? (a) : (b))
#define max(a,b)  ((a) > (b) ? (a) : (b))
biggest  = max (max(a,b), max(c,d))
smallest = min (min(a,b), min(c,d))

给你,没有 if 语句,没有函数(尽管后者是我听说过的最愚蠢和最有害于专家的要求)。

【讨论】:

  • 其中一个限制是没有功能。
  • @JohnKugelman 读到:“在 C 中,如果需要,您可以将 min 和 max 编写为宏”。宏不是函数;-)(不,我实际上认为这不符合要求)
  • “没有功能”的要求太愚蠢了,我什至没有意识到。
【解决方案6】:

这是一个没有 if 或 elseif 或函数或宏的解决方案,而是使用位移位和减法;只使用一个 for 循环:

#include <stdio.h>
int main(){

  int num , max, min;

  printf("Enter four numbers: ");
  scanf("%d", &num);
  max = min = num;

  for(int i = 0; i < 3; i++)
  { 
    scanf("%d", &num);
    max = max * (1 - ( (max-num) >> 31) )
        + num *      ( (max-num) >> 31);
    min = min * (1 - ( (num-min) >> 31) )
        + num *      ( (num-min) >> 31);
  }

  printf("\n%d %d", max, min);
  return 0;
}

(max-num) &gt;&gt; 31) 运算捕获差异的符号,当乘以第二个数字时,得出比较的最小值。

这来自一个旧的 SQL 编码技巧,该技巧在该语言中存在 CASE WHEN 结构之前的日子。

【讨论】:

  • 这是一个很好的方法,但是....它并不能完全满足 OP 的要求。我认为早期的课程中没有教授位操作。
  • @hacks: (1) 它满足 OP 的所有规定要求;您只是在猜测存在未说明的附加要求。 (2) 这是一个很有价值的概念,在对性能要求极高的深度嵌套循环中,可以避免缓存失效。
  • 我从来没有说过这不是一个好概念。我很欣赏你的方法。
  • @fintelia:强调;大约 20 年前。
  • @hacks:另外,可以选择使用 signof 运算符,在提供它的语言中,代替位移。 (如果这样的运算符为零值返回 0,那么这里的公式可能更易于使用。)
【解决方案7】:

试试这个

int max_of_four(int a,int b,int c,int d){
    int max=a;
    if(b>max) max=b;
    if(c>max) max=c;
    if(d>max) max=d;
    return max;
}

没有如果会是这样的

int max_of_four(int a, int b, int c, int d) {
    return ((a > b && a > c && a > d) ? a: ((b > c && b > d) ? b : (c > d ? c : d)));
}

【讨论】:

    【解决方案8】:

    一个想法可能是计算前两个数字的最大值和最小值。然后,你成对比较其余的数字。将每对中较大的一个与当前最大值进行比较,将每对中较小的一个与当前最小值进行比较。这样,您每 2 个元素进行 3 次比较,这比 Arpit 的答案(每个元素进行 2 次比较)效率略高。

    在代码中:

    #include <stdio.h>
    
    int main(int argc, char **argv) {
        int a, b, c, d;
        printf("Enter four integers (separated by space): ");
        scanf("%d %d %d %d", &a, &b, &c, &d);
    
        int max, min;
        if (a > b) {
           max = a;
           min = b;
        }
        else {
           max = b;
           min = a;
        }
    
        if (c > d) {
           if (c > max) {
              max = c;
           }
           if (d < min) {
              min = d;
           }
        }
        else {
           if (d > max) {
              max = d;
           }
           if (c < min) {
              min = c;
           }
        }
        printf("max = %d, min = %d\n", max, min);
        return 0;
    }
    

    【讨论】:

    • 嘘!不必要的比较。
    • @hacks 每次执行只有四次比较。它是计算最小值和最大值问题的最佳比较次数。
    • 拜托了!虽然这是解决方案之一,但不是最优的。我给 +1 只是因为您的代码考虑了用户的输入,这与这里的许多答案不同。
    • 好吧,代码执行并不是唯一的复杂性衡量标准,而且通常是不太重要的衡量标准。另一项衡量标准是代码简洁性。即使 CPU 将执行最少数量的比较,这个答案也包含了许多不必要的比较。因此,与问题中的版本相比,收益并不大。
    【解决方案9】:

    对于绝对性能,即。最少的比较和分配。

    每个级别的 cmets 显示 minmax 的候选值。这个想法是减少每个级别的集合,直到每个集合只有一个项目。这可以通过 4 个比较和 2 个分配来完成。

            // min = a b c d
            // max = a b c d
            if (a <= b)
            {
                // min = a c d
                // max = b c d
                if ( c <= d){
                    // min = a c
                    // max = b d
                    min = a <= c ? a : c;
                    max = b > d ? b : d;
                }else{
                    // min = a d
                    // max = b c
                    min = a <= d ? a : d;
                    max = b > c ? b : c;
                }
            }
            else
            {
                // min = b c d
                // max = a c d
                if ( c <= d){
                    // min = b c
                    // max = a d
                    min = b < c ? b : c;
                    max = a > d ? a : d;
                }else{
                    // min = b d
                    // max = a c
                    min = b < d ? b : d;
                    max = a > c ? a : c;
                }
            }
    

    【讨论】:

    • 截至本文发布之日... 在此页面上最大化信息的解决方案中(而不是分别处理 min 和 max 函数):bradgonesurfing 的此解决方案具有最佳时间复杂度4 个比较和 2 个作业。 Daniel Martin 的解决方案以 4 次比较和 4 次分配的最坏情况排在第二位。 AnT 的解决方案是 3 种中最简洁的,但使用了 4 次比较和 8 次赋值。
    【解决方案10】:
    int max(int a, int b) {
        return a > b ? a : b;    
    }
    
    int max_of_four(int a, int b, int c, int d) {
        return max(a, max(b, max(c, d)));
    }
    
    int main() {
        int a, b, c, d;
        scanf("%d %d %d %d", &a, &b, &c, &d);
        int ans = max_of_four(a, b, c, d);
        printf("%d", ans);
    
        return 0;
    }
    

    【讨论】:

      【解决方案11】:

      这是 C 代码只有 4 个 if 语句。它将最大数量移动到 d 位置,将最小数量移动到一个位置。值 b 和 c 没有在一个序列中正确排列,但是由于要求要求最小值和最大值,因此此代码完成了一项工作:

      #include <stdio.h>
      
      
          int main() {
              int a, b, c, d, temp;
              printf("Enter four digits: ");
              scanf("%d %d %d %d", &a, &b, &c, &d);
              if ( a > b){
                  temp = a; a = b ; b = temp;
              }
              if ( c > d){
                  temp = c; c = d ; d = temp;
              }
              if ( b > d ){
                  temp = b; b = d; d = temp;
              }
              if ( a > c){
                  temp = a; a = c ; c = temp;
              }
              printf("Max %d\nMin %d\n", d, a);
      
              return 0;
          }
      

      【讨论】:

        【解决方案12】:
         Please have at the following    
        
         private int GetLargerValue(int num1, int num2, int num3, int num4)
                    {
                        int largeValue = 0;
                        if (num1 > num2)
                        {
                            if (num1 > num3)
                                largeValue = (num1 > num4) ? num1 : num4;
                            else
                                largeValue = (num3 > num4) ? num3 : num4;
        
                        }
                        else if (num2 > num3)
                            largeValue = (num2 > num4) ? num2 : num4;
                        else
                            largeValue = (num3 > num4) ? num3 : num4;
        
                        return largeValue;
                    }
        

        【讨论】:

          【解决方案13】:
          int max_of_four(int a, int b, int c, int d){
                  int res=a;
                  if(b/res)
                      res=b;
                  if(c/res)
                      res=c;
                  if(d/res)
                      res=d;
                  return res;
              }
          int main() {
              int a, b, c, d;
              scanf("%d %d %d %d", &a, &b, &c, &d);
              int ans = max_of_four(a, b, c, d);
              printf("%d", ans);
          
              return 0;
          }
          

          【讨论】:

            【解决方案14】:

            我看到了这个用于循环和 if else 决策语句的答案,但是我将发布一个我认为会运行得更快并且只使用四个变量的解决方案。就这样吧……

            #include<stdio.h>
            void main()
            {
            int a,b,c,d;
            printf("Enter four numbers of your choice");
            scanf("%d%d%d%d",&a,&b,&c,&d);
            a>b&&a>c?a>d?printf("%d",a):printf("%d" ,d):(b>c&&b>d)?printf("%d",b):c>d?printf("%d", c):printf("%d",d);
            }
            

            【讨论】:

              【解决方案15】:
              #include <stdio.h>
              

              int main(void) {

              int int_1, int_2, int_3, int_4;
              int pair_1_largest = 0, pair_1_smallest = 0;
              int pair_2_largest = 0, pair_2_smallest = 0;
              int quartet_largest = 0, quartet_smallest = 0;
              
              printf("Example: 15 38 8 21\n");
              
              printf("\nEnter four integers: ");
              scanf("%d %d %d %d", &int_1, &int_2, &int_3, &int_4);
              
              if(int_1 > int_2)
              {
                  pair_1_largest = int_1;
                  pair_1_smallest = int_2;
              }
              else
              {
                  pair_1_largest = int_2;
                  pair_1_smallest = int_1;
              }
              
              if(int_3 > int_4)
              {
                  pair_2_largest = int_3;
                  pair_2_smallest = int_4;
              }
              else
              {
                  pair_2_largest = int_4;
                  pair_2_smallest = int_3;
              }
              
              if(pair_1_largest > pair_2_largest)
                  quartet_largest = pair_1_largest;
              else
                  quartet_largest = pair_2_largest;
              
              if(pair_1_smallest < pair_2_smallest)
                  quartet_smallest = pair_1_smallest;
              else
                  quartet_smallest = pair_2_smallest;
              
              printf("The largest number is: %d\n", quartet_largest);
              printf("The smallest number is: %d\n", quartet_smallest);
              
              return 0;
              

              }

              大家好!我是编程初学者,所以不要对我苛刻:) K.N.的“Native C Programming”王有救!

              【讨论】:

                【解决方案16】:

                我们可以在这里使用条件语句。

                int max,max1,max2,min,min1,min2;
                max = (max1 = a>b?a:b)>(max2 = c>d?c:d)?max1:max2 ;
                min = (min1 = a<b?a:b)<(min2 = c<d?c:d)?min1:min2 ;
                

                【讨论】:

                  【解决方案17】:
                  #include <stdio.h>
                  
                  int max_of_four(int a, int b, int c, int d){
                      int mx_A_B = (a > b) * a + (a <= b) * b;
                      int mx_C_D = (c > d) * c + (c <= d) * d;
                  
                      return (mx_A_B > mx_C_D) * mx_A_B + (mx_A_B <= mx_C_D) * mx_C_D;
                  }
                  
                  
                  int main() {
                      int a, b, c, d;
                      scanf("%d %d %d %d", &a, &b, &c, &d);
                      int ans = max_of_four(a, b, c, d);
                      printf("%d", ans);
                      
                      return 0;
                  }
                  

                  【讨论】:

                    【解决方案18】:

                    这不使用任何循环,只有 4 个条件:

                    #include <stdio.h>
                    
                    int main(void)
                    {
                      int i, j, k, l, t, max, min;
                    
                      printf("Enter four integers: ");
                      scanf("%d%d%d%d", &i, &j, &k, &l);
                    
                      if (i < j) {
                        t = i;
                        i = j;
                        j = t;
                      }
                      if (k < l) {
                        t = k;
                        k = l;
                        l = t;
                      }
                      max = (i >= k) ? i : k;
                      min = (j <= l) ? j : l;
                    
                      printf("Largest: %d\n", max);
                      printf("Smallest: %d", min);
                    
                      return 0;
                    }
                      
                    
                      
                    

                    【讨论】:

                      【解决方案19】:
                      int n1, n2, n3, n4;
                      int max, min, max1, min1;
                      
                      printf("Enter 4 integers: ");
                      scanf("%d %d %d %d", &n1, &n2, &n3, &n4);
                      
                      max = min = n1;
                      max1 = min1 = n3;
                      
                      if (n2 > max) max = n2;
                      else min = n2;
                      
                      if (n4 > max1) max1 = n4;
                      else min1 = n4;
                      
                      if (max1 > max) max = max1;
                      if (min1 < min) min = min1;
                      
                      
                      printf("%d, %d\n", max, min);
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2020-11-19
                        • 2015-01-25
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-08-19
                        • 2022-10-07
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多