Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).
For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011
, so the function should return 3.
分析:这个题目是求一个正整数用二进制表示后其中的1的个数。看到题目后不难想到只要让其循环移位,每次和0x01做与操作,统计1的个数即可。
这样我们可以很快的写出代码。
<pre name="code" class="cpp"><span style="font-size:12px;">class Solution {
public:
int hammingWeight(uint32_t n) {
int result = 0;
while(n!=0)
{
if(n&0x01)
++result;
n = n>>1;
}
return result;
}
};</span>
代码中有两点要注意:1)移位符代替除法效率要高;2)这种方法只适合于正整数情况。
在《剑指Offer》中有相同的题目,它对负数的情况也进行讨论。负数右移的时候,最高位符号保持不变。比如0x80000000右移一位的结果就是0xC0000000;如果这个循环持续进行,最后结果在0xFFFFFFFF,程序陷入死循环。
更好的改进方法是对0x01进行移位,然后对其做与,来计算为1的个数。
<pre name="code" class="cpp">class Solution {
public:
int hammingWeight(uint32_t n) {
int result = 0;
unsigned int flag = 0;
while(flag!=0)
{
if(n&flag)
++result;
flag = flag <<1;
}
return result;
}
};
书中还给了另一种解法。
基于这样的事实:把一个整数减去1,再和原整数做与运算,会每次把整数最右边的第一个1变成0。一个数中有多少个1就可以做多少次这样的操作。我们可以把代码进一步改为:
class Solution {
public:
int hammingWeight(uint32_t n) {
int result = 0;
unsigned int flag = 0;
while(flag!=0)
{
if(n&flag)
++result;
flag = flag <<1;
}
return result;
}
};
Reverse bits of a given 32 bits unsigned integer.
For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as00111001011110000010100101000000).
分析:题目要求把一个正整数的每位Bit翻转。这个题目可以用到191题的思想,首先用0x01循环右移,同时0x80000000循环左移。在原数字某位为1的时候(做与运算),让左移翻转数字的同样位置置1(做或运算)即可。代码如下:
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t p1=0x01;
uint32_t p2=0x80000000;
uint32_t result=0;
while(p1)
{
if(n&p1)
result=result|p2;
p1=p1<<1;
p2=p2>>1;
}
return result;
}
};