当前位置: 首页 > news >正文

判断32位整数二进制中1的个数的算法

再转 http://blog.chinaunix.net/uid-20480343-id-1941577.html
今天在CU上看到了关于 “判断32位整数二进制中1的个数的算法” 的问题。因为马上就要下班,没有时间再研究了。只好先把论坛中帖子的地址拷贝下来了。学习ing....

http://dev.bibts.com/32-1-t936968.htm

http://www.chinaunix.net/jh/23/795048.html

在下面的英文网址中,对这个问题有详细的介绍:

http://www.everything2.com/index.pl?node=counting%201%20bits

http://www.everything2.com/index.pl?node=counting%201%20bits%20SPOILER

http://www.everything2.com/index.pl?node_id=1181258

刚开始看到这个问题的时候,我就傻乎乎的开始写代码:

unsigned int FindOneInNumber_00(unsigned int x)
{
    unsigned int i,j=1;
    unsigned int count=0;
    for(i=0;i<32;i++)
    {
        if((x & j) != 0) count++;
        j = j<<2;
    }
    return count;
}
下面是我写的
 



很明显我的这段代码写的是非常糟糕的。每次传过来一个数字,我总是要进行32次扫描。就这一点就可以说我的代码是典型的垃圾代码,那么别人是不是有简洁一点的代码呢。在上面的三个英文网址中找到了一些东西。

unsigned int FindOneInNumber_01(unsigned int x)
{
    unsigned int n;
    for(n=0; x; x >>= 1)
        if (x & 1) n++;
    return n;
}

在英文文档中,原作者给出的第一种方法。看到这样的代码,俺只能说自己太笨,代码写起来太傻。不就是查查一个数字中 1 的个数吗?自己为啥非得要把所有的 位 都扫描呢? 这是一个值得想想的问题。 原作者给出的代码已经是很不错了,不过,在下面接着他又给出了第二种解法,这第二种解法,更是简洁 优雅 。

unsigned int FindOneInNumber_02(unsigned int x)
{
    unsigned int n;
    for(n=0; x; n++)
        x &= x-1;
    return n;
}
原作者给出的第二种方法明显的要优于第一种方法。两者的程序中,循环体执行完后,n表示 1 个个数。x的值变为 0 。两者都达到了目的,循环次数也是一样的。但是二者的区别就在于 第二种方法不用 执行条件判断跳转。当数据量的比较大的时候,二者的差距还是蛮大的。

原文作者又给出第三种方法来解决这个问题:

unsigned FindOneInNumber_03(unsigned int x)
{
    const unsigned MASK1  = 0x55555555;
    const unsigned MASK2  = 0x33333333;
    const unsigned MASK4  = 0x0f0f0f0f;
    const unsigned MASK8  = 0x00ff00ff;
    const unsigned MASK16 = 0x0000ffff;

    x = (x&MASK1 ) + (x>>1 &MASK1 );
    x = (x&MASK2 ) + (x>>2 &MASK2 );
    x = (x&MASK4 ) + (x>>4 &MASK4 );
    x = (x&MASK8 ) + (x>>8 &MASK8 );
    x = (x&MASK16) + (x>>16&MASK16);
    return x;
}

原文作者的一个朋友又给出一种方法,【查表法】,不过,这样要浪费一定的主存。这种方法也是一个很不错的方法,不过,在单片机下开发的时候,就是个问题的了。象我们公司在单片机上开发游戏,所有的能够给 图片、声音、程序的所有ROM空间仅仅 8MB,采用这种方法就是很不明智的一种选择了。
unsigned numbits_lookup_table[256] = {
    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
    3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
    3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
    4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
    3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
    6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
    4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
    6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
    3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
    4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
    6, 7, 6, 7, 7, 8
};
unsigned FindOneInNumber_04(unsigned int x)
{
    unsigned n;
    
    n = numbits_lookup_table[x & 0xff];
    n += numbits_lookup_table[x>>8  & 0xff];
    n += numbits_lookup_table[x>>16 & 0xff];
    n += numbits_lookup_table[x>>24 & 0xff];
    
    return n;
}
【本程序在Dev C++ 4.9.9.2 下编译通过】

转载于:https://www.cnblogs.com/zhangfeionline/p/5889370.html

相关文章:

  • json化 datatable
  • 乐视云视频 接口开发 结合百度编辑器
  • css 布局
  • code异常处理
  • 直线方程公式
  • python中的tab补全功能添加
  • 一个失败团队的养成
  • 利用CSS3 clip-path裁剪各种图形。
  • [BZOJ4016][FJOI2014]最短路径树问题
  • 计数问题
  • 排序算法总结第二弹----冒泡排序---javascript描述
  • Codeforces710C【数学】
  • 【20160924】GOCVHelper 图像处理部分(2)
  • bash的工作特性及其使用方法
  • ajax执行时提示
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • 2019.2.20 c++ 知识梳理
  • ES6 ...操作符
  • HTTP--网络协议分层,http历史(二)
  • JDK9: 集成 Jshell 和 Maven 项目.
  • miaov-React 最佳入门
  • Python_网络编程
  • vue:响应原理
  • Vue2.x学习三:事件处理生命周期钩子
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 分布式任务队列Celery
  • 服务器从安装到部署全过程(二)
  • 诡异!React stopPropagation失灵
  • 好的网址,关于.net 4.0 ,vs 2010
  • nb
  • 国内开源镜像站点
  • ​插件化DPI在商用WIFI中的价值
  • ​你们这样子,耽误我的工作进度怎么办?
  • # include “ “ 和 # include < >两者的区别
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #HarmonyOS:软件安装window和mac预览Hello World
  • %@ page import=%的用法
  • (1)(1.11) SiK Radio v2(一)
  • (TOJ2804)Even? Odd?
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转) Face-Resources
  • ***详解账号泄露:全球约1亿用户已泄露
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • 、写入Shellcode到注册表上线
  • .form文件_SSM框架文件上传篇
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Core 中插件式开发实现
  • .NET6实现破解Modbus poll点表配置文件
  • .Net的C#语言取月份数值对应的MonthName值
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
  • [ 蓝桥杯Web真题 ]-布局切换
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [FFmpeg学习]从视频中获取图片