【问题标题】:Finding MAX of numbers without conditional IF statements c++ [duplicate]在没有条件IF语句的情况下查找最大数字c ++ [重复]
【发布时间】:2013-03-27 09:28:59
【问题描述】:

所以我也从用户输入中得到两个数字,并在不使用 if 语句的情况下找到两个数字的最大值。

该课程是初学者课程,我们也使用了我们已经知道的内容。我有点想出办法,但只有先输入最大数字的数字才有效。

#include <iostream>
using namespace std;


int main()
{
int x = 0, y = 0, max = 0;
int smallest, largest;

cout << "Please enter 2 integer numbers, and i will show you which one is larger:      ";
cin >> x >> y;

smallest = (x < y == 1) + (x - 1);
smallest = (y < x == 1) + (y - 1);

largest = (x < y == 1) + (y - 1);
largest = (y > x == 1) + (x + 1 - 1);

cout << "Smallest: " << smallest << endl;
cout << "Largest: " << largest << endl;



return 0;
}

这就是我目前所拥有的,但在放入不同的测试数据后,我发现它只适用于 4,5 或 6,7 等数字。但是数字之间有超过 2 个空格,它们不会,例如 4,8 或 5, 7。任何帮助将不胜感激。

【问题讨论】:

  • 当然不是。如果y&gt;xlargest = (y &gt; x == 1) + (x + 1 - 1); 只返回x+1。 (例如 y=9, x=8,这将返回 9,但不是因为 9 更大)
  • 您分配给同一事物两次,忽略第一次。你涵盖了 if 语句吗?
  • 为什么不用if语句?
  • 你可以使用std::max吗?
  • 试试这个:int Max = (x &gt; y ? x : y);

标签: c++ if-statement


【解决方案1】:

我在 Cracking the Coding 面试书中看到了这个问题。

让我们尝试通过“重新措辞”这个问题来解决这个问题 我们将重新措辞这个问题,直到我们得到一些删除所有 if 语句的东西

改写1:如果a > b,则返回a;否则,返回 b
改写2:如果(a - b) 为负,则返回b;否则,返回一个
改写 3:如果 (a - b) 为负数,则令 k = 1;否则,让 k = 0 返回 a - k * (a - b)
改写 4:设 c = a - b 设 k = c 的最高位 返回 a - k * c

int getMax(int a, int b) { 
    int c = a - b;
    int k = (c >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1; 
    int max = a - k * c; 
    return max;
}

来源:http://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X

编辑:即使 a-b 溢出,此代码也有效。 令 k 等于 a-b 的符号,如果 a-b >=0,则 k 为 1,否则 k=0。令 q 为 k 的倒数。当 a 为正数或 b 为负数时,上面的代码会溢出,反之亦然。如果 a 和 b 有不同的符号,那么我们希望 k 等于 sign(a)。

/* Flips 1 to 0 and vice-versa */
public static int flip(int bit){
   return 1^bit;
}

/* returns 1 if a is positive, and 0 if a is negative */
public static int sign(int a){
     return flip((a >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1);
}

public static int getMax(int a, int b){
   int c = a - b;
   int sa = sign(a-b);   // if a>=0, then 1 else 0
   int sb = sign(a-b);   // if b>=1, then 1 else 0
   int sc = sign(c);     // depends on whether or not a-b overflows

   /* If a and b have different signs, then k = sign(a) */
   int use_sign_of_a = sa ^ sb;

   /* If a and b have the same sign, then k = sign(a - b) */
   int use_sign_of_c = flip(sa ^ sb);

   int k = use_sign_of_a * sa + use_sign_of_c * sc;
   int q = flip(k);   //opposite of k

   return a * k + b * q;
}

【讨论】:

  • 适用于较小的数字,但在某些极端情况下这会被破坏 - 其中a - b 将是&lt; std::numeric_limits&lt;int&gt;::min()
  • 您假设一个整数包含 32 位。为什么不使用(sizeof(int) * CHAR_BIT) - 1
  • 是的,你是对的。感谢您指出!
【解决方案2】:

这是一个有趣的解决方案:

int max_num = (x>y)*x + (y>=x)*y;

【讨论】:

    【解决方案3】:

    假设您已经涵盖了位运算符,您可以这样做:

    max = a-((a-b)&((a-b)>>(sizeof(int)*8-1)));
    

    这是基于 @user93353 在上面的 cmets 中指出的 Mathematically Find Max Value without Conditional Comparison 的解决方案。

    如果你真的只是想避免 if 语句,而不是一般的比较,这可能有点过头了。

    【讨论】:

    • 我认为您的意思是 &&(逻辑)而不是 &(按位),因为在后一种情况下,如果 b>a,它将返回 a-a-b = b,因为设置了最高位。但是如果 a>b 则为 a-((a-b)&0x00),这显然会导致仅当 b == 0 时才返回“a”,并且可能在其他一些情况下。
    • 绝对是按位和 (&)。它对我来说适用于几个测试用例。例如:a=5,b=4,max=5; a=1,b=200,最大值=200; a=0,b=-1,最大值=0; a=-200, b=-300, max=-200;
    • 你说得对,我脑子有问题。
    【解决方案4】:

    您可以尝试使用此代码为两个输入变量找到 maxmin

    ((a > b) && (max = a)) || (max=b);
    ((a < b) && (min = a)) ||  (min=b);
    

    对于三个输入变量,您可以使用类似的方法:

    int main()
    {
        int a = 10, b = 9 , c = 8;
        cin >> a >> b >> c;
        int max  = a, min = a;
        // For Max
        ((a > b) && (a > c) && (max=a)) || 
               ((b > c) && (b > a) && (max=b)) || 
               (max=c) ;
    
        // For min
        ((a < b) && (a < c) && (min=a)) || 
             ((b < c) && (b < a) && (min=b)) || 
             (min=c) ;
    
        cout << "max = " << max;
        cout << "and min = " << min;
        return 1;
    }
    

    一次运行是:

    :~$ ./a.out 
    1
    2
    3
    max = 3 and min = 1
    

    编辑

    感谢@Tony D:此代码将因负数而失败。

    可以尝试对两个输入的负数进行此操作以找到最大值(不确定):

    ((a > b) && ( a > 0 && (max = a))) ||  ((b > a) && (max = b)) || (max = a);
    

    【讨论】:

    • -1 "您可以使用此代码找到最大 ((a &gt; b) &amp;&amp; (max = a)) || (max=b); - 考虑 a == 0b = -1a &gt; btrue,所以 max = a 被评估但产生 @987654333 @ - 整体表达式为(false) || (max = b),所以max = b 也运行,结果为-1
    • @TonyD 好的,我没有尝试负数 Tony。是的,你是对的。我会尝试使用正确的解决方案进行更新。如果您想改进我的答案,我会很高兴:)
    • @TonyD 你能检查编辑部分我对最大值是否正确?
    • 哦,哎呀......这太复杂了,看着它让我头疼 - 当代码不明显正确时,这令人担忧。为了测试,我将您的代码放入char mymax(char a, char b),然后放入for (int ia = -128; ia &lt;= 127; ++ia) for (int ib = -128; ib &lt;= 127; ++ib) if (mymax(ia, ib) != std::max(ia, ib)) std::cout &lt;&lt; "broken for " &lt;&lt; ia &lt;&lt; ' ' &lt;&lt; ib &lt;&lt; '\n'; - 它会产生65022 行错误......
    • 不是我说格里杰什的地方,我很高兴你为所欲为。我认为这种方法有潜力(您的第一个版本适用于许多(全部?)正值),并且人们看到我测试您最后一次检查 a 和 b 输入的每个组合的蛮力方式的潜在价值允许有符号类型(使用 char,因为 8 位在时间上是可管理的,并且说明了 int 的问题,在 charint 之间进行仔细转换以使测试工作)。
    猜你喜欢
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 2020-02-08
    • 2011-07-15
    • 2020-11-19
    • 1970-01-01
    • 2011-11-24
    相关资源
    最近更新 更多