当x有奇数个1时返回1,retrun 1 when x contains an odd number of 1s

xiaoxiao2021-02-27  108

  看到了这一个练习题,写一个函数,要求当x有奇数个1时返回1,否则返回0,只能用12个以内的逻辑、算术和位运算

  /* retrun 1 when x contains an odd number of 1s;0 otherwise

    Assume w=32*/

 

看到这道题时,想到笨一点的方法就是一个个去数吧,if(x&0x1==0){ k++;} 循环后将k取模得到结果,但这样不符规定啊。

于是脑海中就想到奇数和偶数的定义和它们之间的差别特性等等,应该是用这些来解题??

首先想到的是奇数加奇数等于奇数,偶数加偶数等于偶数。。。然而发现这些没用

 

好吧,是我想错了方向,不应该把X当成一个整体的数,这题目是要让你数x里面1的个数,是让你数数,人家从来都没说要你数的X是一个数!!!

这下醒悟过来后,我开始将X想象成一堆数,一堆0和1。

假如X里面只有一个0和一个1时,答案是1;两个1时,答案是0,两个0时,答案是0

这像什么?没错就是:异或运算^

现在将这堆数(偶数个)分成两部分,前一半和后一半的数一 一对应进行异或运算,得到的结果再分成更少的两部分,重复上一个步骤,直到只剩一个数,就是答案了。

例如:1101,分成11和01两部分,11^01=10,10再分成1和0,1^0=1。得到结果

 

//c实现代码 int odd_ones(unsigned x) { /* retrun 1 when x contains an odd number of 1s;0 otherwise Assume w=32*/ x ^= x>>16;//x右移16位,然后将x的高16位和低16位异或,忽略32位数结果里面不相干的高16位。 x ^= x>>8; x ^= x>>4; x ^= x>>2; x ^= x>>1;//现在最右面的一位就是结果了 x&=0x1;//将不相干的高31位置零得到结果 return x; }

 

将操作反过来,想想下面的代码又是什么意思???

 

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

 

想到了吗??

 

 

 

 

 

 

 

异或操作反过来是错的!!!下面的代码是错的!!!

 

过了好久无意中又看到了这篇博文,想了想,才发现下边的算法也是对的。

这位仁兄的这篇文章有说明:

https://blog.csdn.net/Aaron_Koyalun/article/details/78001832

 

转载请注明原文地址: https://www.6miu.com/read-13706.html

最新回复(0)