0
点赞
收藏
分享

微信扫一扫

Integer.bitCount(int i)方法


昨天,在LeetCode刷题的时候,在Submission中看到一个执行用时很少的代码,里面用到了Integer.bitCount(i)方法,没明白是做什么的,看了注释后,才知道这个bitCount(i)方法是统计整形数字i对应的二进制中,有几个1,但是写法却让人迷惑,下面就来分析一下。

题目链接:1558. 得到目标数组的最少函数调用次数

先搜索了几篇文章看了下,大概意思渐渐理解了,做下记录。Integer.bitCount(int i)方法_System

先上一段代码,即bitCount()的原型:

public static int bitCount(int i) {
    i = (i & 0x55555555) + ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i & 0x0f0f0f0f) + ((i >>> 4) & 0x0f0f0f0f);
    i = (i & 0x00ff00ff) + ((i >>> 8) & 0x00ff00ff);
    i = (i & 0x0000ffff) + ((i >>> 16) & 0x0000ffff);
    return i;
}

十六进制

二进制

0x55555555

01010101010101010101010101010101

0x33333333

00110011001100110011001100110011

0x0f0f0f0f

00001111000011110000111100001111

0x3f

00000000000000000000000000111111

Integer.bitCount(int i)方法_System_02

……

第五行,每次看二进制的32位,统计32位中1的个数,再放到原位置上。

此时,bitCount()的原型就能理解了。再看bitCount()的优化部分。

public static int bitCount(int i) {
    // HD, Figure 5-2
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
}

Integer.bitCount(int i)方法_System_03

public static void main(String[] args) {
    int i = 144358622;
    System.out.println("i的十进制表示:                         " + Integer.toBinaryString(i));
    i = i - ((i >>> 1) & 0x55555555);
    System.out.println("每次看 2位,统计 2位里1的数量,放到原位置上:" + Integer.toBinaryString(i));
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    System.out.println("每次看 4位,统计 4位里1的数量,放到原位置上:" + Integer.toBinaryString(i));
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    System.out.println("每次看 8位,统计 8位里1的数量,放到原位置上:" + Integer.toBinaryString(i));
    i = i + (i >>> 8);
    System.out.println("每次看16位,统计16位里1的数量,放到原位置上:" + Integer.toBinaryString(i));
    i = i + (i >>> 16);
    System.out.println("每次看32位,统计32位里1的数量,放到原位置上:" + Integer.toBinaryString(i));
    i = i & 0x3f;
    System.out.println("最终结果的二进制表示:" + Integer.toBinaryString(i));
}

注意,Integer.toBinaryString()会忽略前导0,分析的时候,需要手动添加,下面是我手动模拟一遍的数据。

00-00-10-00-10-01-10-10-10-11-11-00-11-01-11-10(原始数据)
00-00-01-00-01-01-01-01-01-10-10-00-10-01-10-01(每2位统计)
0000--0001--0010--0010--0011--0010--0011--0011 (每4位统计)
00000001----00000100----00000101----00000110   (每8位统计)
0000000100000101--------0000100100001011       (每16位统计)
00000001000001010000101000010000               (每32位统计)

 

举报

相关推荐

0 条评论