位运算之某整数二进制中一的个数
今天是2016第一天,起得不算太早,但是作为一名Ape 或是一名 Dog ,总是要干点什么,想了想,写一下看到的东西吧
位运算,就是&|~^ >> << 普通的运算为什么要换成位运算呢? 当然是效率呀,一个正整数除以2,与右移是等价的,唯一不同的就是运算的速度有差别,所以对于一些注重运算效率的程序,能用位运算解决就尽量不要用普通运算符解决.
我们的问题是求解二进制中的1的个数,这个问题,的普通方法(不用位运算)可以是对2求模判断是否为1呀.
但是,我们并不想这么做,这么做太low? 不,是效率太低,同时不能再像刚学习C语言那样的接着类的题目了.
如果用位运算解决,我们就不需要把这个整数手工分解了,可以直接在二进制的基础上进行运算,在运算的时候需要用到判断是否为1,和整数除以2,这两个问题对应到位运算中,可以是与1进行"与" 以此来判断是否为1,除以2可以进行移位运算,即右移1位.
似乎这个已经完美的解决了,但是细看题目"整数" ,当然包括正整数与负整数,对于正整数,上面的解法还算不错,但是对于负整数,就可能会出现死循环的情况,所以,这个问题我们仍寻要解决额.
对于这个问题,是因为最高位为1 ,移位时仍然要求最高位为1,但是实际上并不是想的那样,移位时最高位变为了0.所以要解决.
在上一个解法中,是将整数变小(二进制串右移),以此判断最低位是否为1(与1进行与运算) ,那么为什么我们不逆过来想,让二进制1左移(变大) 与整数与运算 以此判断原整数串中一的个数.事实证明这是一个不错的解法,程序最多循环32次.效率也还不错.
上面的问题看似已经解决,事实上也确实解决了,但是如果要更优的时候,还可以有另外一个技巧;
二进制数减去1与自身与运算会使得二进制串中的最右边的一个1变为0.
这样,上面的解法可一是不断的减去1与自身与运算(不断的使得二进制串中的1变为0), 直到所有的1变为0(这个数也就是0了) ,循环的次数,就是1的个数.
Ok 就先写这么多.