算法学习|题目:求二进制中1的个数(基于Java)

题目:求二进制中1的个数

请实现一个函数,输入一个int型整数,输出该数二进制表示中1的个数。
例:9的二进制表示为1001,1的个数为2。

分析:巧用位运算

方法1:从低位到高位逐位判断

已知int类型整数的范围有32位,可通过从低位到高位逐位判断是否为1来计数。
例如整数N,通过判断 N & 1 == 1得到最低位是否为1
通过判断 (N & (1 << 1)) == (1 << 1)得到第二位是否为1
可通过判断(N & (1 << i)) == (1 << i)得到第i+1为是否为1
(若结果为true则为1,否则为0)
方法1图解

方法2:逐位无符号右移依次判断最低位

与方法1类似,通过将原数的二进制形式逐位无符号右移,即从第二位起依次移动到最低位并与1相与,可得该位是否为1
可通过判断(N >>> i) & 1 == 1得到第i+1位是否为1
(若结果为true则为1,否则为0)
方法2图解

方法3:消除所有的1直到原数为0

依次将最低位的1到最高位的1消掉,最后结果为0时,记录消除操作的次数可得1的个数
知识补充:
1010 - 1 = 1001
1 0 0 1
& 1 0 1 0
= 1 0 0 0 - - - 消除了最低位的1

1000 - 1 = 0111
0 1 1 1
& 1 0 0 0
= 0 0 0 0 - - - 消除了下一位的1 --> 结果为0 消除2次 1的个数为2
总结: (x - 1) & x --> 这个操作可以消除最低位的1
方法3图解

代码展示

import java.util.Scanner;
public class Demo{
	public static void main(String[] args) {
		//实现键盘录入
		Scanner sc = new Scanner(System.in);	
		System.out.println("请输入任意一个整数:");
		//N为键盘录入的任意整数
		int N = sc.nextInt();
		//定义一个count变量,用于记录1出现的个数
		int count = 0;
		//获得N的二进制形式
		String B = Integer.toBinaryString(N);
		
		
		//使用方法1:逐位左移
		for(int i = 0;i < 32;i++) {
			if((N & (1 << i)) == (1 << i)) {
				count++;
			}
		}
		//输出N的二进制形式
		System.out.println(N+"的二进制形式为:"+B);
		//输出该数对应二进制形式的1的个数
		System.out.println(N+"的二进制形式中1的个数为:"+count+"个");
		
		
		
		//使用方法2:逐位右移
		count = 0;	//将方法1中使用过的count赋回0
		for(int i = 0;i < 32;i++) {
			if(((N >>> i) & 1) == 1) {
				count++;
			}
		}
		//输出该数对应二进制形式的1的个数
		System.out.println(N+"的二进制形式中1的个数为:"+count+"个");
		
		
		//使用方法3:消除所有1
		int M = N;
		count = 0;
		while(M != 0) {
			M = (M - 1) & M;
			count++;
		}
		//输出该数对应二进制形式的1的个数
		System.out.println(N+"的二进制形式中1的个数为:"+count+"个");
	}
}

运行结果

运行结果
骚话时刻:
位运算可真是个好东西
学学学,学到秃头
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值