位运算——数0的个数
来源:互联网 发布:南昌工程学院网络 编辑:程序博客网 时间:2024/04/30 19:17
最简单的方法
移位来运算:N>>=1;然后用N 同1进行“与”运算,来判断末尾是否为1
下面有更快的方法;
快速的方法:判断某一位置是否是1的一个方法,v&=(v-1);
最经典:
位操作比除、余操作的效率高了很多。但是,即使采用位操作,时间复杂度仍为O(log2v),log2v为二进制数的位数。那么,还能不能再降低一些复杂度呢?如果有办法让算法的复杂度只与"1"的个数有关,复杂度不就能进一步降低了吗?
同样用10 100 001来举例。如果只考虑和1的个数相关,那么,我们是否能够在每次判断中,仅与1来进行判断呢?
为了简化这个问题,我们考虑只有一个1的情况。例如:01 000 000。
如何判断给定的二进制数里面有且仅有一个1呢?可以通过判断这个数是否是2的整数次幂来实现。另外,如果只和这一个"1"进行判断,如何设计操作呢?我们知道的是,如果进行这个操作,结果为0或为1,就可以得到结论。
如果希望操作后的结果为0,01 000 000可以和00 111 111进行"与"操作。
这样,要进行的操作就是 01 000 000 &(01 000 000 - 00 000 001)= 01 000 000 &00 111 111 = 0。
因此就有了解法三的代码:
循环中直接计算1的数量(即后面的方法3)
如何只数'1'的个数?如果一个数字至少包含一个'1'位,那么这个数字减1将从最低位开始依次向高位借位,直到遇到第一个不为'0'的位。依次借位使得经过的位由原来的'0'变为'1',而第一个遇到的那个'1'位则被借位变为'0'。
36 d = 100100 b
36-1 d = 100011 b
如果最低位本来就是'1',那么没有发生借位。
现在把这2个数字做按位与:n & (n-1)的结果是什么?
2个数字在原先最低为'1'的位以下(包括这个位)的部分都不同,所以结果是保留了其他的'1'位。
36 & (36-1) d = 100000 b
这个结果刚好去掉了最低的一个'1'位
int bit_count(unsigned int n)
{
int count;
for(count = 0; n; n &= n - 1)
{
count++;
}
return count;
}
由于直接跳过'0'位,这个方法比上面的要略微快一些。
2016.8.21更新
复习的时候,经过几个月知识的积累。发现树状数组中的lowbit也可以解决这个问题
如下,因为lowbit就是取一个数的最后的“1”位
while (n) {ans++;n^=lowbit(n);}
- 位运算——数0的个数
- 位运算 —— 一个数二进制形式尾端为 0 的个数
- 《剑指Offer》位运算——求二进制数中1的个数
- 二进制数中1的个数,位运算的境界
- 位运算--求一个 数二进制中1的个数
- 位运算—统计文本文件中汉字的个数
- 位运算数的运算
- 位运算--统计一个数的二进制序列中1的个数
- C语言位运算应用一:求一个数的二进制表示中1的个数
- 神奇的位运算——二进制中1的个数
- 【剑指offer】2.4.3位运算——面试题10:二进制中1的个数
- 位运算——二进制中1的个数相关题目
- 剑指offer——面试题10:位运算之二进制中1的个数
- 二进制中1的个数(java)——位运算
- 位运算:二进制中1的个数
- 二进制中1的个数----位运算
- 位运算------二进制中1的个数
- 两个数不同的位个数
- Gradle多模块的项目构建
- <MZ&DC联考>D2 T2
- 【HUSTOJ】1091: 回形方阵
- Ehcache 整合Spring 使用页面、对象缓存
- UINavgationController中覆写preferredStatusBarStyle方法不执行的问题
- 位运算——数0的个数
- Aidl
- 关于ajax
- mysql编译安装
- 灰度共生矩阵的生成和理解
- 杭电1330
- redhat5配置本地yum
- 二进制中1的个数的多种解法解析以及完整c语言代码
- eventBus学习