【问题标题】:Using only 4 'if' statements - Find Largest and Smallest of 4 integers仅使用 4 个“if”语句 - 查找 4 个整数中的最大和最小
【发布时间】:2022-04-07 04:39:06
【问题描述】:

我一直在学习推荐的初学者书籍中的一些基本练习:C Programming: A Modern Approach (2nd Edition)

问题指出:使用尽可能少的 if 语句来确定用户输入的四个数字中的最大值和最小值。 四个 if 语句就足够了。 -- 因为这个问题是在本书介绍循环、数组和函数之前提出的,所以我假设不应该使用这些。

另外,我知道有一个与此类似的question,但是没有一个符合我想要实现的要求。

  1. 仅使用 4 个 if 语句
  2. 没有 for 循环。

我首先想到的是使用逻辑 or 运算符,但如下所示,使用了八个 if 语句。而且这个方法很长而且效率不高:

    int a, b, c, d;

printf("Enter 4 intgeres to find largest and smallest: ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);

if (a > b && a > c && a > d)
    printf("Largest: %d\n", a);
if (b > a && b > c && b > d)
    printf("Largest: %d\n", b);
if (c > a && c > b && c > d)
    printf("Largest: %d\n", c);
if (d > a && d > a && d > c)
    printf("Largest: %d\n", d);

if (a < b && a < c && a < d)
    printf("Smallest: %d\n", a);
if (b < a && b < c && b < d)
    printf("Smallest: %d\n", b);
if (c < a && c < b && c < d)
    printf("Smallest: %d\n", c);
if (d < a && d < a && d < c)
    printf("Smallest: %d\n", d);

return 0;

接下来,我继续执行以下代码,这将是一个更好的解决方案:

    int a, b, c, d;

printf("Enter 4 intgeres to find largest and smallest: ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);

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\n", max, min);

return 0;

但是,仍然不能满足使用 4 个if 语句的要求。我想知道我是否可以进一步缩短我的代码。请原谅这个问题的基本性质。任何建议将不胜感激。

【问题讨论】:

  • 顺便说一句,即使没有? :,也可以使用零ifs,只使用&amp;&amp;||
  • 是的,我知道使用条件表达式可以通过zero if s 解决这个问题。但是要求声明我使用if 语句来实现结果。 (4 个就足够了)
  • 只有if,所以没有else or else if?
  • 虽然我不知道它是否有帮助(我还没有真正通过它)但如果a &gt; b &amp;&amp; b &gt; c 那么它遵循a &gt; c
  • @Stefan, else if 可以使用但是,如果我弄错了,请纠正我,else if 也被认为是一个 if 语句。因此,在我的最后一个解决方案中,我使用了 6 个 if 语句。

标签: c if-statement


【解决方案1】:

我们可以使用分而治之的方法来解决这个问题。

想象我们的输入 = [a, b, c, d]

我们想从 [a,b] 和 [c,d] 中找到答案

然后合并最终的解决方案以找到答案。

if(a > b) swap(&a,&b); // solve [a,b]
if(c > d) swap(&c,&d); // solve [c,d]
if(a > c) swap(&a,&c); // find minimum from [a,b] and [c,d]
if(d > b) swap(&b,&d); // find maximum from [a,b] and [c,d]

// a will store the minimum value.
// b will store the maximum value.

奖金(如何在 C 语言中交换数字)

void swap(int *a,int *b) {
    int c = *a;
    *a = *b;
    *b = c;
}

【讨论】:

  • swap 存在于 C++ 中,但不存在于 C 中,并且无法在 C 中以允许您按照自己的方式调用它的方式实现。但是,如果这意味着是伪代码,那很好,在这种情况下,它只会有助于指出您意识到缺少位。
  • 是的,我知道。我假设他可以轻松编写 swap(a,b) 函数。我将编辑我的原始解决方案。
  • @algojava:swap(a, b) 可以通过 C11 通用宏实现(尽管我同意它不像 C++ 中的 std::swap 那样优雅)。例如,您可以定义#define swap(a, b) _Generic((a), int: swapi)(&amp;a, &amp;b),其中swapi 与您的swap 基本相同。见godbolt.org/g/SFMdps
【解决方案2】:

以下应该可以工作。

它使用前两个ifs 计算max1 = max(a, b)max2 = max(c, d),以及min1 = min(a, b)min2 = min(c, d)

那么最大值等于max(max(a, b), max(c, d)) = max(max1, max2)。 (第三个if。)

并且最小值等于min(min(a, b), min(c, d)) = min(min1, min2)。 (第四个if。)

int a, b, c, d;

// ...

int min, max, max1, max2, min1, min2;

if (a > b) // 1
{
    max1 = a;
    min1 = b;
}
else
{
    max1 = b;
    min1 = a;
}

if (c > d) // 2
{
    max2 = c;
    min2 = d;
}
else
{
    max2 = d;
    min2 = c;
}

if (max1 > max2) // 3
    max = max1;
else
    max = max2;

if (min1 < min2) // 4
    min = min1;
else
    min = min2;

奖金

ifs.

int a, b, c, d;

// ...

int min = a, max = a;
b < min && (min = b);
c < min && (min = c);
d < min && (min = d);
b > max && (max = b);
c > max && (max = c);
d > max && (max = d);

【讨论】:

  • 这个练习让读者了解快速排序等分而治之的排序技术。 “零如果”是作弊,cond &amp;&amp; expressionif。这个问题可能会更好地表达为“仅使用 4 次比较”。
  • 这个解决方案是否被认为比我提出的第二种解决方案更有效,因为它的 if 语句更少?
  • @Rizzo:是的,HolyBlackCat 的第一个示例比您建议的示例更有效。局部临时变量“便宜”;编译器通常可以优化它们(即,只将它们保存在寄存器中)。 Divide and conquer algorithm 维基百科页面可能会阐明像这样拆分问题的想法。将问题拆分并绘制decision trees,是一种非常有用的设计技术,您可以考虑学习,以解决一般问题。
【解决方案3】:
#include <stdio.h>

int main ()
{
    int num1, num2, num3, num4;
  
     printf("enter the numbers: ");
     scanf("%d %d %d %d", &num1, &num2, &num3, &num4);

     int large1 = num1, low1 = num2, low = num3, large = num4;
     if (num1 <= num2) {
         large1 = num2;
         low1 = num1;
     }
     if (num3 >= num4) {
         large = num3;
         low = num4;
     }
     if (large < large) {
         large = large1;
     }
     if (low > low1) {
         low = low1;
     }
     printf("%d\n", large);
     printf("%d\n", low);
     return 0;
}

【讨论】:

    【解决方案4】:
    #include <stdio.h>
    
    int max_of_four(int a,int b, int c, int d)
    {
        int max=0;
        max = (a > b ? (a > c ? (a > d ?   a :  d) :  (c > d ? c : d) ) : (b > c ? (b > d ? b : d>c? d : c ) : c>d? c : d)) ;
    
       return max;
    }
    
    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;
    }
    

    【讨论】:

    • 三元运算符的使用似乎显然是题外话。此外,您只计算最大值,而不是最小值。
    【解决方案5】:

    这是一个带有单个 if 语句的替代解决方案:

    #include <stdio.h>
    
    int main() {
        int a, b, c, d;
      
        printf("enter the numbers: ");
        if (scanf("%d%d%d%d", &a, &b, &c, &d) == 4) {
            int lo1 = a * (a <= b) + (a > b) * b;
            int hi1 = a * (a >= b) + (a < b) * b;
            int lo2 = c * (c <= d) + (c > d) * d;
            int hi2 = c * (c >= d) + (c < d) * d;
            int lo = lo1 * (lo1 <= lo2) + (lo1 > lo2) * lo2;
            int hi = hi1 * (hi1 >= hi2) + (hi1 < hi2) * hi2;
            printf("%d %d\n", hi, lo);
            return 0;
        } else {
            return 1;
        }
    }
    

    【讨论】:

      【解决方案6】:

      这是一个非常有创意的问题。我只使用两个 if 语句解决了您的问题。

      int a = 22, b = 25, c = 100, d = 4;
              int max = 0, min = 0;
              if ((a > b ? (a > c ? (a > d ? max = a : max = d) : max = c) : (b > c ? (b > d ? max = b : max = d) : max = c)) == 1)
              {
                    //Control never goes inside this loop
              }
              else if ((a < b ? (a < c ? (a < d ? min= a : min= d) : min= c) : (b < c ? (b < d ? min = b : min = d) : min = c)) == 1)
              {
                   //Control never goes inside this loop
              }
              printf("Maximum Value is:%d and Minimum Value is: %d", max, min);//at this statement max and min will have appropriate values
      

      【讨论】:

      • ?:if/else 的语法糖。
      • 可能相同,但它们在 C 中属于不同的分类。"?:" 是条件运算符,"if else" 是语句。并且被告知不要使用 if 语句超过 4 次。它没有提到我们不能使用条件运算符。您最好在对任何人进行负面评价之前检查您的事实。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-16
      • 1970-01-01
      • 2018-03-26
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 2020-04-21
      相关资源
      最近更新 更多