只用一次+计算三个数和


四则运算符中只能用一次+,-*/都不能使用,实现计算a、b、c三个数的和,算法高手帮忙给解答一下!

趣味 算法

淒然D奈落 12 years, 4 months ago

a + b = (a ^ b) + ((a&b)<<1) = (a ^ b) ^ ((a&b)<<1) + ((a^b)&((a&b)<<1)) = ...
这么写下去一次加法都不需要行吗……等右边那个括号里面的移位移到32的时候,右边那一项就没了……不过表达式会长得不能看……

只用第一步,把c的内容也加进来:
a + b + c = (a ^ b) + ((a&b)<<1) + c
= ((a ^ b) + c) + ((a&b)<<1)
= (a ^ b ^ c) + (((a ^ b)&c)<<1) + ((a&b)<<1)
(注意到移位的性质,移位等于*2,因此和加法是满足分配律的)
= (a ^ b ^ c) + ((((a ^ b)&c) + (a&b))<<1)
注意a ^ b与a&b不同时为1,因此(a ^ b)&c与(a&b)不同时为1,也就是说这个加法不会产生任何进位
因此
a + b + c = (a ^ b ^ c) + ((((a ^ b)&c) | (a&b))<<1)
(a + b + c = (a ^ b ^ c) + ((((a ^ b)&c) ^ (a&b))<<1)也一样)

因为((a ^ b)&c) | (a&b) = a&(~b)&c | (~a)&b&c | a&b = a&(~b)&c | (~a)&b&c | a&b&c | a&b&(~c) = a&c | b&c | a&b
所以最后结果也可以写成
a + b + c = (a ^ b ^ c) + ((a&c | b&c | a&b)<<1)
这种对称而美妙的形式

回头来看其实意思也很明确:(a ^ b ^ c)是三个数相加每一位直接产生的结果,(a&c | b&c | a&b)是三个数相加每一位产生的进位。三个数相加的情况下不可能直接产生超过1的进位。

PLS131 answered 12 years, 4 months ago

Your Answer