深入理解计算机系统家庭作业2.65

 
 
 
 
 
 
 
 
 
 

这是道神题,涉及到了分治,bit操作,这里给出详细思路。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CODE

int odd_ones(unsigned x)
{
  x^=x>>1;
  x^=x>>2;
  x^=x>>4;
  x^=x>>8;
  x^=x>>16;
  return x&1;
}

分析

x^=x>>1;                 (xm.n是 xm xor xn)(自己画的图片,不对齐,见谅)


x^=x>>2


x^=x>>4

x^=x>>8

x^x>>16

相信大家已经发现规律了


每进行一次,x第一个bit 异或多了一倍从 1 -> 2 -> 4 -> 8 -> 16 -> 32。从而实现了每一位的xor,并将结果放在了x的第一个bit。

接着,有些人可能不明白为什么要xor,xor的作用是什么。

要知道xor的在这个题目里发挥的作用,先看真值表

如果两位都是0,或都是1,那么证明这个数里有2个0或者2个1(有点废话hehe),那么这个数bit是奇还是偶不由这二位决定。

如果两位是1 0,或者 0 1 ,那么证明这二个bit排列的结果是奇。所以可以直接用1来代替这两bit。(感觉这里我解释的不是很清楚,见谅哦)

经过上面的分析,得到:x第一个bit放着32位bit的异或。如果是 0 0,或者1 1,变为0(奇偶不用决定),如果是1 0 ,或者0 1,变为1(将两位化为一位).最后x第一个bit就能决定该数里有偶数个1还是奇数个了。

结语

最后说一点:为什么有分治的思想呢,因为可以这么想:先判断XnXn-1这两个bit里bit位为1是奇还是偶,是奇,变为1

是偶数,变为0.

再判断Xn+2Xn+1  XnXn-1,此时Xn+2Xn+1  XnXn-1进过上一步,都是一bit

这样便是分治的思想了。

append:

不敢相信,在2.66,也用到了这种思路。

/*Generate mask indicating leftmost 1 in x.Assume w=32. 
**/
同样,先给出代码
int leftmost_one(unsigned x)
{
  x|=x>>1;
  x|=x>>2;
  x|=x>>4;
  x|=x>>8;
  x|=x>>16;
  return x^(x>>1);
}

哇,超眼熟的,有了上面的思路,这题当然也轻车熟路啦

x|=x>>1(2)(4)(8)(16)

x第一个bit与前面所有bit或

x第二个bit与前面所有bit或

。。。。。。

x第31个bit与第32个bit或

x第32个bit与0个bit或

这样,就能将x转换为[00000..........111111111111]也就找到了最高位。

总结

我认为:这应该是一种bit的算法,但是我不知道叫什么,总结为:


如果op是&,?????

如果op是|,找最高位

如果op是^,bit中1的0数量是奇还是偶

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

reference:

https://blog.csdn.net/zhanyu1990/article/details/24936663

http://www.matrix67.com/blog/archives/264

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如果通过我的文章理解了,就给个打赏个赞大笑大笑,如果还有疑问,可以发邮件和我讨论 peanwang @outlook.com,或者[email protected]

猜你喜欢

转载自blog.csdn.net/weixin_41256413/article/details/79937907
今日推荐