编写一个算法,告诉我三个中只有两个和两个数字是否相同

时间:2012-10-22 18:12:16

标签: algorithm math

我遇到了看似简单的算法问题。我试图在3次或更少的操作中完成它,我有理由相信它可以通过数学解决,但我无法弄清楚(问题的来源没有答案)。

编辑:

(a[0] == a[1] + a[0] == a[2] + a[1] == a[2]) == 1

是我最初的想法,但我想看看是否可以在更少的操作中完成(1比较是一个操作)。

4 个答案:

答案 0 :(得分:7)

假设3个数字为abc

(b == c) ? (a != c) : (a == b || a == c)
  • 如果(a,b,c)=(1,1,1),那么我们将调用b == c(true)然后调用a != c(false)并完成。
  • 如果(a,b,c)=(1,1,2),那么我们将调用b == c(false)然后调用a == b(true)并完成。
  • 如果(a,b,c)=(1,2,1),那么我们将调用b == c(false)然后调用a == b(false)和a == c(true )并完成了。
  • 如果(a,b,c)=(2,1,1),那么我们将调用b == c(true)然后调用a != c(true)并完成。
  • 如果(a,b,c)=(1,2,3),那么我们将调用b == c(false)然后调用a == b(false)和a == c(false )并完成了。

所以最多进行3次比较。

?:||还有2个条件分支点,但OP不计算它。

答案 1 :(得分:3)

取决于您认为的“操作”......

以下仅使用数组中的3个比较。然而,有一个第四个比较,== 1以确保只有一个匹配。我相信你可以使用大量的分支来有条件地消除一些比较,但如果这是一个优化,分支可能会使它表现更差。

正好有3个结果:

  • 没有一个值相同(总和为零)
  • 两个将是相同的(总和是一个)
  • 这三个都是相同的(总和是三个)

if (((array[0] == array[1]) +
     (array[1] == array[2]) +
     (array[0] == array[2])) == 1)
{
    // stuff
}

这与分支进行比较以实现最多3次比较和仅需要2的路线:

if (array[0] == array[1]) // if these are equal
    return !(array[1] == array[2]); // and these are not equal, return true
else
    return (array[0] == array[2]) || (array[1] == array[2]); // otherwise, if these are equal, we already know the others are not equal because we already tested them so return true

答案 2 :(得分:2)

您可以编写表达式:

((b == a) | (b == c)) ^ (a == c)

具有恒定成本,总是执行三次比较和两次逻辑运算。没有分支机构,处理器应该很容易。

取决于架构,

((b == a) || (b == c)) ^ (a == c)

可能更快(这个执行两次或三次比较,一次逻辑操作和一次分支)。

答案 3 :(得分:1)

我的尝试...

return (ab ? (!ac) : (ac ? true : bc));

其中:

ab = (a==b)
ac = (a==c)
bc = (b==c)

这使用2或3次比较,有时以条件跳跃为代价。让我们检查每个案例的操作次数:

  • a == c == b:(a == b)+ jump +(a == c)+否定[返回!= c] 4次操作
  • a == b!= c:与上述相同,4次操作
  • a!= b == c:(a == b)+ jump +(a == c)+ jump +(b == c)[返回此值] 5次操作< / LI>
  • a == c!= b:(a == b)+ jump +(a == c)+ jump [return true] 4次操作
  • a!= c!= b:与上述相同,4次操作

当然,这取决于你的操作概念......如果不考虑跳跃......