常规解法
通常我们会通过反复左移实现,这样32位整数需要循环32次。
对于右移的特殊说明:
对于负数,算数右移(>>)会出现死循环,需要使用逻辑右移(>>>)。
以下为解答:
private int NumberOf1(int n) {
int count = 0;
int flag = 1;
while (flag != 0) {
if ((n & flag) != 0) {
count++;
}
flag = flag << 1;
}
return count;
}
高级解法
思路:反复减1,将结果与上一次结果与运算,直至为0。减1的次数就是1的个数。
首先分析把一个整数减去1的情况。对于非0整数,其二进制表示中至少有1位是1,下面做出假设:
- 假设最后一位是0
若最右边的1在第m位,那么减1之后,第m位由1变为0,m位之后的都由0变为1,m位之前的都不变。此时做一个与运算,就把m位处理掉了。
例如:1100 - 1 = 1011;1100 & 1011 = 1000。只剩下m位之前的1。 - 假设最后一位是1
分析同上,也是只剩下最后一位之前的1。
总结:把一个整数减1,再和原整数做与运算,就会把该整数最右边的1变为0。
以下为解答:
public int NumberOf1(int n) {
int count = 0;
while (n != 0) {
n = n & (n-1);
count++;
}
return count;
}