Brian Kernighan 算法

算法基础 -- Brian Kernighan 算法初识 【代码】算法基础 -- Brian Kernighan 算法初识。 阅读详情

一、算法背景

Brian Kernighan 算法是一种高效计算二进制数中 1 的个数(即汉明权重,Hamming Weight)的技巧。相比于逐位检查的常规方法,它只遍历值为 1 的位,而不是所有位,因此在二进制中 1 较少时尤为高效。


二、核心原理

算法的关键在于一个非常巧妙的位运算恒等式:n & (n - 1) 的结果是将 n 的二进制表示中最低位的 1 变为 0。

为什么?

  • 对于任意非零整数 n,n - 1 会:

    • 将最右侧的 1 变为 0

    • 将该位右边的所有 0 变为 1

    • 左侧高位保持不变

例如:n = 10100(20)

text

n       = 10100
n - 1   = 10011
n & (n-1) = 10000  ← 最低位的 1 被清除了

因此,每次执行 n &= n - 1,就能消除一个 1,循环次数正好等于 1 的个数。


三、代码实现

int countBits(int n) {
    int count = 0;
    while (n != 0) {
        n &= (n - 1);
        count++;
    }
    return count;
}

四、复杂度分析

维度复杂度说明
时间复杂度O(k)k 为二进制中 1 的个数,远优于固定循环 32/64 次
空间复杂度O(1)只使用常数个变量

五、边界情况与注意事项

1. 负数的处理

在 Java 中,有符号整数使用补码表示。Kernighan 算法使用 n & (n - 1) 操作,对负数同样有效,因为:

  • n - 1 在补码下仍然会将最低位的 1 变为 0,该位右侧的 0 变为 1

  • & 操作后,该最低位的 1 被清零,高位保持不变

  • 循环 while (n != 0) 会在所有 1 被清除后结束(包括符号位)

  • // Java 中直接使用 int(包括负数)完全没问题
    public static int countBits(int n) {
        int count = 0;
        while (n != 0) {
            n &= (n - 1);
            count++;
        }
        return count;
    }
    
    System.out.println(countBits(-1));   // 补码全1 → 32
    System.out.println(countBits(-13));  // 补码中1的个数 → 30

2. n = 0 的情况

循环条件 while (n != 0) 为 false,直接返回 0,结果正确。

System.out.println(countBits(0));   // 输出 0

六、相关位运算技巧

表达式效果常见用途
n & -n提取最低位的 1(lowbit)树状数组(Fenwick Tree)
n ^ (n - 1)生成从最低位到第一个 1 的掩码位运算扩展
n | (n - 1)将最低位的 1 之后所有位变为 1位域合并

七、示例演示

以 n = 13(二进制 1101)为例:

步骤当前 nn-1n & (n-1)消除的 1计数
初始1101———0
①110111001100最低位1
②110010111000第二位2
③100001110000最高位3

最终 count = 3,即 1101 中有 3 个 1。


八、其他统计方法对比

方法循环次数优点缺点
逐位检查固定 32/64 次简单直观即使 1 很少也要循环所有位
Kernighan等于 1 的个数高效,位数越稀疏越快仍然依赖循环次数
查表法(分块)固定次数(如 4 次查表)速度极快需要额外内存
内置指令(__builtin_popcount)O(1) 硬件级最快非跨平台
深入解析Brian Kernighan算法:高效统计二进制中1的个数 位运算是计算机底层数据处理的核心技术,它直接操作二进制位,执行效率极高。其原理基于计算机的二进制表示和逻辑门电路,通过AND、OR、XOR等基本操作实现复杂功能。在算法优化和系统编程领域,位运算的技术价值尤为突出,能够显著提升程序性能,减少资源消耗。典型的应用场景包括嵌入式开发、高性能计算、数据压缩和网络协议处理等。本文聚焦于Brian Kernighan算法,该算法巧妙地利用 `x & (x-1)` 这一位操作技巧,高效地统计无符号整数中位‘1’的个数,是理解**位运算优化**和**算法时间复杂度**的经 阅读详情

相关推荐

Brian Kernighan算法详解及Java实现

Brian Kernighan算法,也被称为布莱恩·柯林汉算法,是一种用于统计二进制数中位为1的个数的高效算法。该算法通过不断清除二进制数中最右侧的1来计算1的个数,直到二进制数变为0为止。Brian Kernighan算法的基本思想是通过n与n-1进行按位与运算,可以将n的最右侧的1清除掉,直到n变为0为止。该算法利用按位与运算和迭代的方式高效地统计二进制数中1的个数,适用于处理大量的二进制数据。在每次循环中,我们将n与n-1进行按位与运算,并将结果重新赋值给n。方法计算n中1的个数,并将结果打印输出。

HackLogic的博客 529

BrianKernighan算法

看左程云大佬的算法课的时候觉得很精妙的算法,就整理总结了下来 https://space.bilibili.com/8888480

LB_bei的博客 716

导出库的版本_Windows下PaddleOCR在C++中的推理部署(CPU版本)CMake + VS2017

PaddleOCR是一个与OCR相关的开源项目,不仅支持超轻量级中文OCR预测模型,总模型仅8.6M(单模型支持中英文数字组合识别、竖排文本识别、长文本识别,其中检测模型DB(4.1M)+识别模型CRNN(4.5M)),而且提供多种文本检测训练算法(EAST、DB)和多种文本识别训练算法(Rosetta、CRNN、STAR-Net、RARE)。本文将教大家通过PaddleOCR(CPU版...

weixin_31304817的博客 1914

位运算|比特位计数、汉明距离

位运算|比特位计数、汉明距离

weixin_43217281的博客 892

从门禁到支付:Uniapp+NFC开发避坑指南(支持Mifare Classic)

本文详细介绍了Uniapp结合NFC技术开发门禁与支付系统的实战指南,特别针对Mifare Classic卡片进行深度优化。内容涵盖环境配置、设备兼容性处理、卡片安全机制解析以及高性能读写优化策略,帮助开发者快速实现跨平台的智能硬件交互解决方案。

t1u2v的博客 751

分子动力学模拟学习1-采用AmberTools21的MCPB.py构建金属蛋白的top文件

分子动力学模拟学习1-采用AmberTools21的MCPB.py构建金属蛋白的top文件

weixin_45011386的博客 3827

位操作符的总结 Brian Kernighan算法

文章目录1 Brian Kernighan 算法2 判断一个数字n的比特位中1的个数2 leetcode231. 2的幂3 201. 数字范围按位与4 不创建临时变量,交换两个数字 1 Brian Kernighan 算法   这个算法的意思是,对任何一个数 nnn,n&(n−1)n\&(n-1)n&(n−1)的结果是nnn的比特位最右端的1变为0的结果。例如,n=12,n−1=11,11&12=8n=12,n-1=11,11\&12=8n=12,n−1=11,11&

weixin_43688483的博客 6262

滤波器初步入门(非常全面)

主要关注的是-3dB这个点,-3dB就是截止频率所对应的点,我们把功率降至50%以下的信号定义为被衰减掉了(但要跟实际情况相结合,有些信号衰减-3db不够,需要衰减更多)-3dB这个点对应我们的电压来说是0.707。设计电路可以留一定的余量,如果你把4k设计为截止频率,那么4k时候衰减倍数为-3dB通常是不够的,你可以将截止频率设为2k,那么4k的衰减就可以达到15dB(假设),根据自己的需要去设计对应的截止频率。理想的滤波器是当输入的信号频率大于截止频率时,大于部分的频率对应的电压信号直接归0。

yybyybds的博客 5720

Brian Kernighan算法

讨论范围n>0,即正整数 快速判断的方法是n&n-1为0则是2的幂,当n>0时,分两种情况,二进制下一种是只有1位是1,另一种是至少2位是1,则当只有一位时,-1有取反的效果,n&n-1相当于n&~n绝对是0。当至少两位为1,那么,减一时,最高位的1必定不受影响,所以n&n-1必定不是0.由此可以区分一个数是否为2的幂。 ...

SSS 586

Navicat从入门到精通:数据库管理全攻略

本文系统梳理Navicat数据库管理工具的核心应用体系。从基础的安装与多类型数据库连接入手,详解数据库与数据表的创建、修改、删除等操作逻辑;深入数据增删改查的可视化与 SQL 语句双重操作模式,结合Excel/SQL文件的导入导出场景提供实操指南。同时覆盖数据备份恢复、跨库同步等进阶功能,以及视图、存储过程等高级应用。通过对比同类工具突出Navicat的易用性与功能性优势,并针对连接失败、字符乱码等常见问题提供解决方案,帮助读者从零基础掌握数据库全生命周期管理,提升数据操作效率与安全性。

邓邓子的博客 1897

90. 将 SAP ABAP 内表内容本地导出成 Excel 文件

这里文件扩展名为 csv,全称是 Comma-Separated Values,意思是这种类型的文件内容,由逗号分隔。除了 ASC 之外,另一个可用的选项是 BIN,适用于 PDF,EXE 等二进制文件的导出。支持海量的输入和输出参数,我们这个简单的本地导出场景里,大部分参数都用不上。这个分隔符的添加逻辑,编写在上图红色高亮矩形框内,使用的语法是。本教程有学习者向我提问,询问如何将 ABAP 某某函数的某某输出参数的值,导出成本地 Excel 文件。把这个内表的内容,下载到本地,以本地文件的方式保存。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1743

461.汉明距离·Brian Kernighan 算法

BrianKernighan 算法

m0_64560763的博客 490

Altium Designer应用技巧5: Altium Live账号的获得

为了更好的应用Altium Designer,我们需要得到一个Altium Live账号,但从其英文或者中文官方网站取得,都需要7个工作日的时间,而且对于个人用户来说,并不是100%都能够获取到。本文介绍一种,从俄罗斯Altium官方网站获取账号的方法,可以立即使用。     1、点击http://live.altium-ru.com/#Join网址进入俄罗斯Altium官方网站,Altiu

snmplink的博客 1万+

Brian Kernighan 算法——计算一个整数的二进制表示中 1 的个数

在二进制表示中,一个数num减去 1(即num - 1)会将该数最右边的 1 变为 0,并且将这个 1 右边的所有 0 变为 1。

2403_88007973的博客 413

AgentScope实战训练营-Java开发HITL人机协作AI应用完整指南

本文手把手带你从零搭建一个基于 Spring Boot WebFlux + AgentScope + 通义千问的人机协作(HITL)AI 聊天应用。项目涵盖流式对话、工具调用、高危操作确认、对话中断、动态 MCP 工具接入、中英文双语界面等完整功能。文章从环境准备、pom.xml 配置、DTO 数据模型、Hook 机制、AgentService 核心服务、ChatController 接口到前端 HTML/CSS/JS 实现,逐一讲解每行代码的设计意图,并附带 REST API 接口说明、测试场景、常见问题

program哲学 713

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【位操作笔记】位计数算法 Brian Kernighan的方法

位计数算法 Brian Kernighan方法位计数算法说明位计数算法代码32位数的位计数代码8位数的位计数代码算法来源算法计算过程[参考资料] 位计数 位计数(Counting bits set),指的是计算一个数里bit位置1的个数,例如一个8位数0xea = 0b1110 1010,位置1的个数为5。 算法说明 该算法每次清除从最低位到最高位数的第一个为1的位,运算次数取决于二进制位中1的个数。 位计数算法代码 32位数的位计数代码 unsigned int count(unsigned int v)

761

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Brian Kernighan’s 算法处理二进制中1的个数——位运算

Brian Kernighan’s 算法是一种高效计算一个整数的二进制表示中1的个数的方法<<<<<<<<;

qq_44630195的博客 383

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

上一篇: Servlet学习
下一篇: 进程与线程通信方式
xuhaoyu_cpp_java
博客等级 码龄2年 2粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值