快速计算某一整数中的二进制比特“1”的数目、以及定位二进制比特“1”的位置

在实际应用中,经常需要进行快速计算某一整数中的二进制比特“1”的数目、及快速定位二进制比特“1”的位置的工作,而且要求能高效进行。对该问题的常规方法是采用逐个比特移位进行判断,其循环处理的次数取决于待处理数据的比特长度,即若有n个比特待处理,则需要循环n次,如下的方法可大幅减少循环的次数,其复杂度仅仅取决于待处理数据的"1"比特的个数,即若待处理数据的"1"比特的个数为m个,则只需要循环m次即可。具体代码如下:

/*
  obin.c
  dump integer in binary form, count bit '1',
  locate the postion of bit '1'
  ------------------
  [email protected]
  Mon Aug 21 15:55:29 CST 2023
  ---- screenshot ----
  00 00000000 (0)
  01 00000001 (1) 0
  02 00000010 (1) 1
  03 00000011 (2) 0 1
  04 00000100 (1) 2
  05 00000101 (2) 0 2
  06 00000110 (2) 1 2
  07 00000111 (3) 0 1 2
  08 00001000 (1) 3
  09 00001001 (2) 0 3
*/

void ob(char i)
{
    static int k;
    if (i != 0) {
        k++;
        ob(i / 2);
        printf("%d", i % 2);
    } else {
        printf("%0*d", sizeof(i) * 8 - k, 0);
        k = 0;
    }
}

int b13(char i)
{
    return (i == 0 ? 0 : 1 + b13(i & i - 1));
}

int log2(unsigned i)
{
    int k = 0;
    while (i = i / 2) {
        k++;
    }
    return k;
}

void b1_pos(char i)
{
    int k;
    while (i) {
        k = i - (i & i - 1);
        printf("%d ", log2(k));
        i &= i - 1;
    }
}

int main()
{
    int i;
    for (i = 0; i < 16 * 2; i++, puts("")) {
        printf("%02d ", i);
        ob(i);
        printf(" (%d) ", b13(i));
        b1_pos(i);
    }
}

输出结果示例如下:

06 00000110 (2) 1 2

第一列表示待处理的十进制整数(此例中为6),第二列为对应整数的二进制表示形式(此例中为00000110),第三列表示该整数中的二进制比特“1”的数目(此例中为(2),表示有两个二进制比特“1”),此后的各列表示该该整数中的各二进制比特“1”出现的位置 (此例中比特“1”出现 第1位和第2位,其中的最低比特为位置序号为0,而后从右向左依次递增1。) 。关于该方法的的具体解释,请参见 3行代码为何能求得二进制数中1比特的个数_jocks的博客-CSDN博客

你可能感兴趣的:(java,算法,数据结构)