问题描述:给出一个整数,输出这个整数的二进制表示中1的个数。
算法思路1:(移位)第一步:判断二进制表示中最后一位是不是1,如果是1,计数器加1,否则不加;第二部:丢掉最后一位,继续递归第一步,直到这个数等于0,返回计数结果。(正数情况下)
package com.study;
public class Test {
public static void countOneFreq(int n){
int count = 0;
while(n>0){
if((n&1)==1) //判断最后一位是不是1
count++;//如果是1,计数器加1
n>>=1;//向右移位
}
//当n==0,end while
System.out.print(count);
}
public static void main(String[] args) {
countOneFreq(7);
}
}
输出结果"3
算法评价:算法的复杂度为O(n),其中n表示二进制数的位数
算法思路2:n&(n-1)由于要求出1的个数,把二进制表示中的每个1看成独立的。例如7位111,那么7-1=110,7&(7-1)=110。(正数情况下)
package com.study;
public class Test {
public static void countOneFreq(int n){
int count = 0;
while(n>0){
if(n!=0) //如果还存在1
n=n&(n-1);//消除一个1
count++;//每消除一个1就计数一次
}
//当n==0,end while
System.out.print(count);
}
public static void main(String[] args) {
countOneFreq(8);
}
}
输出结果为1
算法评价:这个算法的复杂度为O(m),其中m是1的个数。
算法思路3:考虑正数和负数
1的二进制:00000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码(反码+1):
11111111 11111111 11111111 11111111
∵:-1 的二进制即 1 的二进制补码
∴:-1 的二进制为:
11111111 11111111 11111111 11111111
package com.study;
public class Test {
public static void countOneFreq(int n){
int count = 0;
while(n!=0){//当二进制存在1 <pre name="code" class="java"> n=n&(n-1);//消除一个1
count++;//计数器加1}//当n==0,end while System.out.print(count);}public static void main(String[] args) {countOneFreq(-1);}}
输出结果:32
算法评价:这个算法的复杂度为O(m),其中m是1的个数。