题目
给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。
(今天的题解法非常精彩,别看没几行代码,理论可不少)
输入
5
1 2 3 4 5
输出
1 1 2 1 2
public class 位运算_二进制中1的个数 {
public static void main(String[] args) {
//拿到数据个数
Scanner in = new Scanner(System.in);
int n = in.nextInt();
while (n-- > 0) {
//data是当前接收的数据 res也就是当前data的1的个数,初始为0
int res = 0, data = in.nextInt();
while (data > 0){
//Lowbit操作(data & -data)
//data每次减去二进制最后一位1的十进制值,减去多少次,就代表有多少个1
data -= data & -data;
res ++;
}
//输出当前data的1的个数
System.out.print(res + " ");
}
System.out.println();
}
}
Lowbit理论:
假设x的二进制为: 010100...10...000
-x为: 101011...01...000
-x+1: 101011...10...000
那么x & -x+1: 000000...10...000
也就得到了最一位1的位置
在java和c++中-x都代表的是x的补码,也就是-x+1,这就解释了我代码中的(data & -data)
拿x=5举例,二进制:0101
第一次拿到0001,也就是5-1,1出现一次
第二次拿到0100,也就是4-4,1出现两次
最后输出1出现的次数
这样应该就很清晰了吧~
声明:算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流