《剑指offer》第十五题:二进制中1的个数
题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数,例如,把9表示成二进制是1001,有2位是1。如果输入9,输出为2
解法一:
java实现:
int NumberOf1Test01(int n){
int count=0;
while(n>0){
if((n&1)!=0){
count++;
}
n=n>>1;
}
return count;
}
C++实现:
int NumberOf1Test01(int n) {
int count = 0;
while (n) {
if (n & 1) {
count++;
}
n = n >> 1;
}
return count;
}
思路:将该数字与1(只有最右面一位数字为1)进行位运算,比较该数字最右面一位数字是否为1,比较完之后将该数字右移一位,继续比较右侧第二个数字,以此类推。
但是,该解法是错误的,错误原因:若该数字是负数,右移会在左面第一位补1,最终导致无限循环。
解法2:
java实现:
int NumberOf1Test02(int n){
int count=0;
int flag=1;
while(flag!=0){
if((count&flag)!=0){
count++;
}
flag=flag<<1;
}
return count;
}
C++实现:
int NumberOf1Test02(int n) {
int count = 0;
unsigned int flag = 1;
while (flag) {
if (count & flag) {
count++;
}
flag = flag << 1;
}
return count;
}
思路:利用flag和n的各位进行比较,flag为1,和n的右边第一位进行比较,然后flag右移,在和第二位进行比较,以此类推,等到和n的最后一位比较完后,再右移,为0,比较结束。
解法3:
java实现:
int NumberOf1Test03(int n){
int count=0;
while(n!=0){
n=(n-1)&n;
count++;
}
return count;
}
c++实现:
int NumberOf1Test03(int n) {
int count = 0;
while (n ) {
n = (n - 1) & n;
count++;
}
return count;
}
思路:n-1将把n各位中,第一个出现的1变为0,该位右边的各位设成1,和n进行&运算,将把该位右边的1全部化成0(0与1&运算还为0),再赋值给n,将消除一个为1的位,循环该过程,将把1全部消除,求得count。
结论:把一个整数减去1再和原来的整数做位运算,结果将为把该整数最右边的1变成0.

浙公网安备 33010602011771号