【博客177】二进制中1的个数:方法三
内容: 记录求二进制中1的个数的另一种好方法:汉明重量计算算法
最近在看redis源码,发现redis求二进制中1的个数的方法很赞,记录一下:
代码:
int vpSWAR(int i)
{i = (i & 0x55555555) + ((i>>1) & 0x55555555);i = (i & 0x33333333) + ((i>>2) & 0x33333333);i = (i & 0x0F0F0F0F) + ((i>>4) & 0x0F0F0F0F);i = (i * 0x01010101) >> 24;return i;
}
原理解析:
SWAR算法分为四步:一:计算每两位为一组的二进制形式包含1的个数
i = (i & 0x55555555) + ((i>>1) & 0x55555555);二:计算每四位为一组的二进制形式包含1的个数i = (i & 0x33333333) + ((i>>2) & 0x33333333);三:计算每八位为一组的二进制形式包含1的个数i = (i & 0x0F0F0F0F) + ((i>>4) & 0x0F0F0F0F);四:直接计算32位包含1的个数。对于32位的数来说,可以将其按每8位一组分为4组,直接计算经过前三步计算之后得到的结果,那么要计算其总共包含多少个1,只需计算四个八位加起来是多少个1,就像:A+B+C+D。而ABCD表示的是不同的位区间范围。不过不同位置,不能直接相加,该如何快速计算A+B+C+D的值呢?就是将B、C、D分别左移8位、16位、24位,使其分别与最高位的A对齐:方法如下:将数字i分别左移0位、8位、16位、24位然后相加的结果,就是 i * 0x01010101 ,因为i + (i << 8)+ (i << 16) + (i << 24) = i * (1 + 1 << 8 + 1 << 16 + 1 << 24) = i * 0x01010101 对于32位数字来说,左移之后超过32位的部分会被舍弃,低位补0,将左移之后得到的四个数字相加,结果的高8位的值就是原32位数包含的1的个数,要得到这个值,只需要将结果右移24位,将值放在低8位即可。
使用举例:redis
redis使用这个算法和查表法两种配合来求二进制中1的个数:
1.当二进制位数小于128时,使用查表法
2.当二进制位数大于128时,使用此算法,然后按每次32bit计算来叠加
【博客177】二进制中1的个数:方法三相关推荐
- 剑指Offer:二进制中1的个数
题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h>int wrong_count_1_bits(int n) // 错误解法: ...
- VIPKID:笔试题(数组中和为0的一对数的数量,十进制转二进制中1的个数)
1. 求数组中的和为0 的一对数的数量 注意,需要用到set import java.util.Scanner;public class Main{public static void main(St ...
- 牛客题霸 [二进制中1的个数] C++题解/答案
牛客题霸 [二进制中1的个数] C++题解/答案 题目描述 输入一个整数,输出该数32位二进制表示中1的个数.其中负数用补码表示. 题解: 判断1的个数 x&(-x)=2^k 有点类似于树状数 ...
- [剑指Offer]12.二进制中1的个数
题目 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路 把一个整数减去1,再和原整数做与运算,会把整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多次这样 ...
- (转)快速统计二进制中1的个数
大牛博客插眼:https://blog.csdn.net/u013243347/article/details/52220551 证明在大牛的博客里,直接挂代码吧: 时间复杂度从logn下降到了O(二 ...
- 基于visual Studio2013解决面试题之0410计算二进制中1的个数
题目 解决代码及点评 /*求一个数中,二进制表示方式中1的个数范例算法采用分治思想,通过位操作计算二进制中1的个数 */#include <iostream> using name ...
- C/C++求一个整数的二进制中1的个数
求一个整数的二进制中1的个数 收藏 题目:输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 分析:这是一道很基本的考查位运算的面试题.包 ...
- 剑指Offer #11 二进制中1的个数(想不到的骚操作)
题目来源:牛客网-剑指Offer专题 题目地址:二进制中1的个数 题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 题目解析 对于这种涉及位运算的题目,我们首先要了解基本的位 ...
- 《剑指offer》-- 把数组排成最小的数、丑数、二进制中1的个数、表示数值的字符串、替换空格
一.把数组排成最小的数: 1.题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为 ...
最新文章
- Ubuntu下如何用Empathy上QQ
- 写得太好了!树莓派安装docker
- 惠普服务器年销售额,IBM和惠普去年分列服务器收入和发货量第一
- java sort()怎么实现的_Java中Array.sort()的排序原理
- 推荐高质量的公众号,值得跟进学习!
- XCode10 swift4.2 适配遇到的坑
- 最大正方形(洛谷-P1387)
- 触漫机器人_触触+机器人=???
- Apache mod_rewrite
- 重新leetcode第1天——二叉树遍历算法讲解合集
- Ubuntu18.04/16.04 安装glog
- uniapp手写_uniapp 手写 Steps 步骤条
- html word 分页
- JavaScript中如何删除节点?
- lintcode 输出赛程表
- 苹果mac系统下浏览器video无法自动播放问题
- 手摸手写一个互联网黑话生成器
- “破镜”真的没办法“重圆”了吗?
- php反转图片颜色,PHP 图片处理类(水印、透明度、缩放、相框、锐化、旋转、翻转、剪切、反色)...
- CNN2019.11.22