100分求解一道面试题那n&(n-1)

icerlion 2009-08-20 12:25:17
代码如下:


int Fun(int nValue)
{
int nCount = 0;
while (nValue)
{
nValue = nValue&(nValue-1);
++nCount;
}
return nCount;
}



求解Fun(9999);

代码运算结果为8,
为一道面试题,

下来想了半天不得其解,
请各位达人指点迷津。
...全文
422 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xhp7185 2010-08-12
  • 打赏
  • 举报
回复
高明啊!!
PeacefulBY 2009-08-20
  • 打赏
  • 举报
回复
具体地说,如果nValue为奇数,则二进制形式为X...X1,nValue&(nValue-1)的结果为X...X0;
如果nValue为偶数,则二进制形式为X...X10...0,nValue&(nValue-1)的结果为X...X00...0;
相当于每次去掉末尾的1,这样就变成了统计1的个数,&是按位与运算
PeacefulBY 2009-08-20
  • 打赏
  • 举报
回复
Fun就是用于计算nValue变换为二进制后1的个数
arczee 2009-08-20
  • 打赏
  • 举报
回复
UP,学习了
貌似上面的位运算想了半天,终于有点明白了,大概是这样(以8bit为例):
使用0x55作位运算也就是将X的位两两累加,如 11 01 10 11 两两累中后 得到 10 01 01 10,
因为1+1=10 0+1=01 1+0=01 1+1=10 ,所以每二位一组标示X的二位的1的个数。
然后,以0x33对结果做位运算,为什么是0x33呢,因为结果是两位的,所以 是将其两位一组两两相加
得到 0011 0011 这一结果是四位一组的,每四位标示X的四位中的1的个数,
然后 再使用0x0f做位运算,可想而知,得到的是八位组标示的X的每八位中的1的个数。因为X只有八位,所以到此结束,结果为 0011+0011=0000 0110 ,即6个1
更多位数以此类推
whg01 2009-08-20
  • 打赏
  • 举报
回复
《编程之美》中 “求二进制数中1的个数”,122页。
currenttt 2009-08-20
  • 打赏
  • 举报
回复
帮顶,学习
Paradin 2009-08-20
  • 打赏
  • 举报
回复
8l不明白
hua_zhixing_ 2009-08-20
  • 打赏
  • 举报
回复
位运算用得少,半天没反应过来。
呵呵,学习了。
绿色夹克衫 2009-08-20
  • 打赏
  • 举报
回复
每次去掉最后一个1,这样正好可以统计出1的个数。不过统计1的个数有log(n)的方法,最近并行计算比较热,位运算开始被特别重视起来。

贴一段网上的代码吧!

unsigned FindOneInNumber_03(unsigned int x)
{
const unsigned MASK1 = 0x55555555;
const unsigned MASK2 = 0x33333333;
const unsigned MASK4 = 0x0f0f0f0f;
const unsigned MASK8 = 0x00ff00ff;
const unsigned MASK16 = 0x0000ffff;

x = (x&MASK1 ) + (x>>1 &MASK1 );
x = (x&MASK2 ) + (x>>2 &MASK2 );
x = (x&MASK4 ) + (x>>4 &MASK4 );
x = (x&MASK8 ) + (x>>8 &MASK8 );
x = (x&MASK16) + (x>>16&MASK16);
return x;
}
丈八涯 2009-08-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 peacefulby 的回复:]
Fun就是用于计算nValue变换为二进制后1的个数
[/Quote]
正解.
neohope 2009-08-20
  • 打赏
  • 举报
回复
恩,其实每次都是将二进制中最后一个1去掉,呵呵
Paradin 2009-08-20
  • 打赏
  • 举报
回复
每次消掉最后一个1
wuyi8808 2009-08-20
  • 打赏
  • 举报
回复
n为奇数(n的二进制表示的末位为1):
n: xxxxxxxx1
n-1: xxxxxxxx0
n&(n1-): xxxxxxxx0
相当于去掉最右边的一个1。

n为偶数且不等于0(n的二进制表示的末位为0):
n: xxxxx1000
n-1: xxxxx0111
n&(n1-): xxxxx0000
也是相当于去掉最右边的一个1。


所以,程序的效果就是统计传入的参数的二进制表示中1的个数。

如,9999 的二进制表示为: 0010 0111 0000 1111,共有8个1.
hyram 2009-08-20
  • 打赏
  • 举报
回复
LS正解,见编程之美

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧