O(1)复杂度求二进制中1的个数

本文介绍了如何快速计算16位二进制数中1的个数,通过一系列位操作实现。首先将二进制数按位分组,然后逐组进行位运算,最后得到的数值转换为十进制即为1的个数。这种方法在处理大量数据时具有较低的时间复杂度,适用于高效率计算。
摘要由CSDN通过智能技术生成

算法系列第一篇博客文章(本博客第一篇博客文章)

本文讨论最快速求1的个数(应该是最快的)

(以16位二进制数为例)

following are details.

一、问题

先看问题:对于任意16位二进制数n,求二进制数n中数字1的个数。

input

    1025

output

    2

二、代码

先看看核心代码再分析

以c代码为例

short a,b;

a=(n>>0)&0101010101010101;

b=(n>>1)&0101010101010101;

n=a+b;



a=(n>>0)&0011001100110011;

b=(n>>2)&0011001100110011;

n=a+b;



a=(n>>0)&0000111100001111;

b=(n>>4)&0000111100001111;

n=a+b;



a=(n>>0)&0000000011111111;

b=(n>>8)&0000000011111111;

n=a+b;

最终的n转化为十进制数就是原来二进制数n中所含有的1的个数。

三、分析

简单分析一下相信大家已经明白了

假设十六位二进制数

short n=0b0100101101010110;

第一步操作

将n每两位数分为一组

即n为

0100101101010110

执行

a=n&0101010101010101;

以最右端这一组为例看看发生了什么?

那为什么要写(n>>0)呢,没有为什么,因为好看

显然

10&01

结果为00,表示这一组中的右边一位不为1。

执行

b=(n>>1)&0101010101010101;

首先

n>>1

得到

0010010110101011

显然

11&01

结果为01,表示原来这一组中左边一位为1。

执行

n=a+b;

那么

00+01

结果为01,转换为十进制为1,表示这一组中共有1个元素。

那如果结果是10呢,显然01+01得到10,两个01表示了这一组中左右位均为1,也就是两个1,符合二进制数10所对的十进制数。

对每一组应用以上结论,那么这一波操作就能表示分组后每个组中1的个数。

第二步操作

现在n为0b0100011001010101,每个1表示了该组中原来的1的个数。

将n按四位数一组分为四组

即n为

0100011001010101

执行

a=(n>>0)&0011001100110011;

b=(n>>2)&0011001100110011;

n=a+b;

结果n为0b0001001000100010

最后四位0010对应十进制数2,表示进行这一步操作前最后四位中有两个1。

推理方式与第一步操作相同

以此类推进行下面操作

第三步操作

......

第四步操作

......

结果

最终得到的n转换为十进制数便是原来二进制数n中1的数量。

该方法也可用于更高位数的二进制串。

该方法操作步数固定,在处理大量数据时相比于 n&=(n-1) 具有更低的时间复杂度,运算效率更高。

Ok,It's the end of the article.创作不易,转载请标明出处

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值