【问题标题】:Algorithm to return the largest number without IF [duplicate]没有IF返回最大数的算法[重复]
【发布时间】:2017-03-09 04:12:03
【问题描述】:

在一次工作面试中,我的朋友不得不解决这个问题:

开发一个算法,它接收两个变量 a 和 b 都是整数并返回最大值。

示例:如果a = 2b = 7 算法返回7

限制
- 你不能使用 IF 不是任何比较的东西;
- 还有一个不能使用数学或集合类型库,因为它们在内部使用 IF;
- 你不能使用三元运算符,它是一个 IF。

这是最后一个问题,页面底部有以下句子:

Do not look for perfection, just do the best you can.

我们不知道这是一个提示还是只是一个激励短语。

没有提到或需要特定的语言,那么我猜可以使用伪代码或者是逻辑问题。

这里有几个程序员,没有人设法解决。

【问题讨论】:

标签: algorithm if-statement return logic restriction


【解决方案1】:

大家感谢您的帮助。我有机会检查他们正在寻找的答案。
由于它要求一种算法,它不能使用某种编程语言的功能。

答案是:(a+b+|a-b|) * 0,5

但是正如我之前在同一篇文章中评论的那样,|a-b|abs(a-b) 被视为 IF,因为它们测试数字是否为负。

完整正确答案必须实现函数abs(a-b)|a-b|不使用IF,则答案是完整的。

我已经在寻找数学属性和绝对值的演示来解决这个问题,但如果你发现只用简单的数学来实现它,那将非常有帮助。

[编辑] 如果我这样做:√((a-b)^2)。是否需要数学库?

【讨论】:

  • 正如另一个答案中的评论指出的那样,获取 IEEE 浮点数的绝对值是清除符号位的问题。如果不能使用条件,获取二进制补码整数的绝对值会有点麻烦。
  • 这必须在最低级别的编程中完成,对吧?
  • 您可以在 C 中执行此操作。您可以将浮点数转换为 int 并将高位设置为 0。对于整数数据类型,您应该能够使用任何语言的位运算符来执行此操作。
  • 查看我的答案,它展示了如何在不使用任何条件的情况下获取整数的绝对值。
  • 谢谢@JimMischel!我想这是对的。我查看了您标记的可能重复的问题,我理解了。那我就关闭这个帖子。再次感谢。怎么删除?
【解决方案2】:
(a + b + abs(a-b)) / 2

-- 这必须接近可接受。当然 abs() 可以在没有任何 if 语句的情况下实现,您只需将符号位设置为 0。

【讨论】:

  • 为了伟大的正义:在 2-s 补码整数的情况下,仅将符号位归零无济于事。但对于 IEEE 浮点数来说,这确实是正确的做法。
【解决方案3】:

这是 Julia 中的一种解决方案,它应该非常清晰,适用于任何 64 位数据类型。它没有任何控制流或布尔值,只有算术运算和位移。

function f(a,b)
  diff = reinterpret(UInt64,a-b)
  sgn = reinterpret(typeof(a),diff >> 63) #Sign bit of (a-b).
  return (a - sgn*a) + sgn*b
end

【讨论】:

    【解决方案4】:

    由于语言没有明确说明,我们选择 X86 程序集!

    CMP EAX, EBX;   <-- assuming that A is stored in EAX and B is stored in EBX
    CMOVL EAX, EBX; <-- no branching required
    

    [编辑:] 如果 CMP 被认为是 IF 的一部分,我们可以使用第三个寄存器并执行 SUB,这绝对不是:

    MOV EDX, EAX;
    SUB EDX, EBX;
    CMOVL EAX, EBX;
    

    【讨论】:

    • cmp 又是如果你改变了语言
    • 规则 1:"...不是任何 [做] 比较的东西".
    • @neoR,没错。已编辑。
    • 我想只有一个数学表达式的解决方案就足够了
    【解决方案5】:

    您可以将某些内容存储在临时变量中,然后尝试如下操作:

    解决方案来自:- Find maximum of three number in C without using conditional statement and ternary operator

    利用布尔表达式中的短路:

    int max(int a, int b, int c) {
          int m = a;
          (m < b) && (m = b); //these are not conditional statements.
          (m < c) && (m = c); //these are just boolean expressions.
          return m; } Explanation:
    

    在诸如 x && y 之类的布尔 AND 运算中,当且仅当 x 是真的。如果 x 为假,则不计算 y,因为整个 表达式将是错误的,甚至可以在不评估的情况下推断出 是的。这称为短路,当布尔值 表达式可以在不计算其中所有操作数的情况下推导出。

    将这个原则应用到上面的代码中。最初 m 是 a。现在如果 (m

    简而言之,您可以阅读表达式 (m

    测试代码:

     int main() {
             printf("%d\n", max(1,2,3));
             printf("%d\n", max(2,3,1));
             printf("%d\n", max(3,1,2));
             return 0; } Output:
    

    3 3 3 在线演示:http://www.ideone.com/8045P

    注意 max 的实现会给出警告,因为已评估 不使用表达式:

    prog.c:6:警告:未使用计算的值 prog.c:7:警告:值 不使用计算 为避免这些(无害的)警告,您可以 实现最大值为:

     int max(int a, int b, int c) {
          int m = a;
          (void)((m < b) && (m = b)); //these are not conditional statements.
          (void)((m < c) && (m = c)); //these are just boolean expressions.
          return m; }
    

    诀窍在于,现在我们将布尔表达式强制转换为 void,这会导致警告被抑制:

    http://www.ideone.com/PZ1sP

    【讨论】:

    • 我猜'
    • 所以现在你基本上是在说我们甚至不能使用关系运算符
    • 虽然我认为如果你删除关系运算符也没有其他方法,你也可以查看geeksforgeeks.org/…
    • 我不知道正确的答案.. 你说得对,因为如果我们不能使用它们,表达式 ( a + b + |a-b| )/2 也会不正确。绝对值内部有一个 if。 if a > 0 than a elseif a
    • 我曾经看到一个类似这种情况的程序,问题是 printf() 是预定义的,只包含一个变量,面试官要求该人编写一个程序,使用该 printf 打印所有从 1 到 100 的数字,不使用递归、循环、goto 或其他多重 printf。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 2020-04-15
    • 2021-04-30
    • 2018-09-24
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    相关资源
    最近更新 更多