重新开始战斗20-程序员面试宝典-P39_5.5面试题2--求平均数

来源:互联网 发布:linux suspend 编辑:程序博客网 时间:2024/05/08 01:57

面试题2:

下面代码:

Int f(int x,int y)

{

         Return(x&y)+((x^y))>>2);

}

F(729,271)=________

 

首先对于这个题,当然可以一步一步的去算,但是其实这个算法就是求平均数。

 

仔细分析一下:

&:与运算,如果两个数相等,a==b,则a&b ==a == b == (a+b)/2,可以发现,当且仅当两个数相等的时候,&运算可以看成是求平均数。

那么如果两个数不相等的时候呢?

a != b,例如a=10001100,b=110101010.

这个时候可以分解a与b,将他们同1的部分分解开来:

a = 10001000+00000100,b =10001000+01000010

(a+b)/2 =(10001000+10001000)/2+(00000100+01000010)/2

     = (10001000&10001000) + (00000100+01000010)/2

可以发现(10001000&10001000)正是求的是a与b两个数中同一的部分,如果要求a&b同一部分,显然为a&b,所以:

(a+b)/2 =a&b+(00000100+01000010)/2

 

那么(00000100+01000010)/2是什么?

两个数除去同一部分,那么剩下的就是非同一部分,也就是说在非同一位上,两个数不可能同时为1,或者同时为0,那么非同一部分相加,若对应为1与0,则等1,若同时为0,则为0,而且,在对应的同一位上,即两个1,也为0,这样的运算刚好对应了异或运算,然后再除以2,则得到非同一部分的平均数,除以2对应右移1位。

 

因此最后的求平均数公式为a&b+((a^b) >> 1)

0 0
原创粉丝点击