一个unsigned int 数的二进制表示中有多少个1

2023-05-16

这是一道面试题可以用以下的一些方案。
第一种是很容易想到的采用循环的方式并且与1进行位与运算,具体代码如下。
 1 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned  int  GetBitNumOfOne_ByLoop1(unsigned  int  nValue)
 2 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? {
 3求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? const unsigned int nNumOfBitInByte = 8;
 4求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned int nBitMask = 1;
 5求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned int nBitNum = 0;
 6求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? for(unsigned int = 0 < sizeof(nValue) * nNumOfBitInByte i++)
 7求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? {
 8求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?  (0 < (nValue & nBitMask)) ? nBitNum++ 0;
 9求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?  nBitMask<<=1;
10求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? }
11求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? return nBitNum;
12求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?}
13 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?unsigned  int  GetBitNumOfOne_ByLoop2(unsigned  int  nValue)
14 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? {
15求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? const unsigned int nNumOfBitInByte = 8;
16求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned int nBitMask = 1;
17求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned int nBitNum = 0;
18求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? for(unsigned int = 0 < sizeof(nValue) * nNumOfBitInByte i++)
19求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? {
20求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?  (0 < (nValue & nBitMask)) ? nBitNum++ 0;
21求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?  nValue>>=1;
22求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? }
23求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? return nBitNum;
24求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?}

这两种做法很相像,区别就是在对nBitMask进行左移还是对nValue进行右移。
当然了以上的两个方法存在一个问题:不管如何这个函数肯定要循环32次(对于32平台来说)。
那又没有更好的方法?当然有,请看下面:
 1 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned  int  GetBitNumOfOne_ByLoop3(unsigned  int  nValue)
 2 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? {
 3求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned int nBitNum = 0;
 4求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? while(0 < nValue)
 5求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? {
 6求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?  nValue &=(nValue - 1);
 7求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?  nBitNum++;
 8求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? }
 9求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? return nBitNum;
10求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?}

假如使用参数12345(二进制是11000000111001)调用该函数,该函数的执行情况如下:
第一次进入循环
0 < 11000000111001
11000000111001 &= (11000000111001 - 1) 之后 nValue 的值是 11000000111000
nBitNum 的值是1
经过本次循环之后11000000111001 变成了 11000000111000 比之前少了一个1
第二次进入循环
0 < 11000000111000
11000000111000 &= (11000000111000 - 1) 之后 nValue 的值是 11000000110000
nBitNum 的值是2
经过本次循环之后11000000111000 变成了 11000000110000 比之前少了一个1
第三次进入循环
0 < 11000000110000
11000000110000 &= (11000000110000 - 1) 之后 nValue 的值是 11000000100000
nBitNum 的值是3
经过本次循环之后11000000110000 变成了 11000000100000 比之前少了一个1
经过以上3次循环情况的说明,我相信你一定看出了些什么吧。nValue &=(nValue -1),这句
代码实际上就是把nValue 的某位及其以后的所有位都变成0,当nValue最后变成0的时候循环结束,
且nBitNum 记录的就是1的个数。
上面的做法已经很不错了,但是作为程序员的你是否会有疑问,“还有其他的方法吗?”。
有,当然有!请看下面的代码:
 1 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? unsigned  int  GetBitNumOfOne(unsigned  int  nValue)
 2 求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? {
 3求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? nValue = ((0xaaaaaaaa & nValue)>>1+ (0x55555555 & nValue);
 4求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? nValue = ((0xcccccccc & nValue)>>2+ (0x33333333 & nValue);
 5求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? nValue = ((0xf0f0f0f0 & nValue)>>4+ (0x0f0f0f0f & nValue);
 6求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? nValue = ((0xff00ff00 & nValue)>>8+ (0x00ff00ff & nValue);
 7求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? nValue = ((0xffff0000 & nValue)>>16+ (0x0000ffff & nValue);
 8求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? 
 9求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1? return nValue;
10求一个unsigned <wbr>int <wbr>数的二进制表示中有多少个1?}


假如你是第一次看到这些代码,你是否能看明白?呵呵,本人第一次看到这些代码的时候看了好久才感觉
好像有点明白。下面我就以一个例子来说明上面的代码是如何做到的。
假如参数是0xffffffff。
第一行代码:
nValue = ((0xaaaaaaaa &nValue)>>1) + (0x55555555& nValue);
a的二进制表示是:1010
5的二进制表示是:0101
0xffffffff 与 0xaaaaaaaa进行与运算之后是0x10101010101010101010101010101010
然后再进行左移操作后是0x01010101010101010101010101010101
0x55555555 & nValue进行与运算之后是0x01010101010101010101010101010101
然后0x01010101010101010101010101010101 &0x01010101010101010101010101010101
得到0x10101010101010101010101010101010
我们把得到的结果分成16组0x10  10 10  10  10 10  10  10 10  10  10 10  10  10 10  10
每组的10单独来看是不是十进制的2
我们0x01010101010101010101010101010101和0x01010101010101010101010101010101这两个数也按照上面的方法分成
16个组0x01  01 01  01  01 01  01  01 01  01  01 01  01  01 01  01
     0x01  01  01 01  01  01 01  01  01 01  01  01 01  01  01 01
那么这两个数的每一个组都是01 那么两个01里面有几个1,是不是2个。这是2是不是二进制的10,然后16个10组合起来是不是
0x10101010101010101010101010101010

第二行代码:
nValue = ((0xcccccccc &nValue)>>2) + (0x33333333& nValue);
此时nValue是0x10101010101010101010101010101010
c的二进制表示是:1100
3的二进制表示是:0011
0xcccccccc 与 nValue)进行与运算之后是0x10001000100010001000100010001000
然后再进行左移操作后是0x00100010001000100010001000100010
0x33333333 & nValue进行与运算之后是0x00100010001000100010001000100010

然后0x00100010001000100010001000100010 &0x00100010001000100010001000100010
得到0x01000100010001000100010001000100
我们把得到的结果分成8组0x0100 0100 0100 0100 0100 0100 0100 0100
每组的0100单独来看是不是十进制的4 总共有多少个4?是不是8个,8×4=32。

以下的代码:
 nValue = ((0xf0f0f0f0 &nValue)>>4) + (0x0f0f0f0f& nValue);
 nValue = ((0xff00ff00 &nValue)>>8) + (0x00ff00ff& nValue);
 nValue = ((0xffff0000 &nValue)>>16) + (0x0000ffff& nValue);
请自己按照上面的方法做一遍,就会发现规律:第一次32位数分成32组,第二次分成16组,第三次分成8,第四次分成4,第五次分成2组。
如果还是不明白请多看看,然后多选择几个参数进行试验,多试几次肯定会明白的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一个unsigned int 数的二进制表示中有多少个1 的相关文章

随机推荐

  • crosstab 、pivot_table 、groupby比较

    所用数据前五条 目标 生成数据透视图 crosstab pd crosstab index 61 data 39 admit 39 columns 61 data 39 prestige 39 以上代码用于计数 xff0c 如要展示其他数据
  • numpy 矩阵创建

    mat xff1a 分号用于隔开数据 matrix 将ndarray 转为矩阵 bmat 将小矩阵合并成大矩阵 矩阵特有属性与说明 属性 说明 T 返回自身转置H返回自身的共轭转置I返回自身的逆矩阵A返回自身数据的二位数组 xff08 没有
  • numpy 矩阵复制

    纵向复制 横向复制
  • excel 中“万”字处理

    61 IF ISNUMBER FIND 34 万 34 M2 SUBSTITUTE M2 34 万 34 34 34 10000 M2 函数中的3个M2为需要处理单元格所在位置 结果展示如下
  • python groupby 不同列聚合

    dataframe 在groupby后有时候需要对不同的列按照不同的聚合方式聚合 聚合方法如图 xff1a num agg中输入各列数据的聚合方式 可用于多条件groupby
  • dataframe 中万字处理

    df 39 点赞 39 apply lambda x float str x replace 39 万 39 39 39 10000 if 39 万 39 in str x else x astype int
  • VSCode之CMake使用

    一 准备工作 下载 对应平台的VScode安装C 43 43 扩展 安装Cmake 工具扩展 并行需要安装 Cmake xff0c 编译器 xff0c 调试器和构建工具 cmake version 虽然咱们使用VSCode编辑代码 xff0
  • 运行apt-get update后出现错误

    一般错误是如下两种 xff1a 1 一般如果你的ubuntu是中文的设定了地区的 xff0c 错误是如下 xff1a W 无法下载http ppa launchpad net deluge team ppa ubuntu dists nat
  • 表达式求值(含括号的复杂运算)

    具体解析看注释 span class token macro property span class token directive keyword include span span class token string lt bits
  • HttpClient模拟登录总结(不能跳转及跳转后不能登录)

    最近在写一个模拟登录的程序 xff0c 从网上找了很多资料 xff0c 都没能有一个完整的例子可成功跳转登录后的页面 xff0c 现把我的代码拿来与大家分享一下 xff0c 希望可以帮到一些人吧 其原理是 xff1a 通过HttpClien
  • JestonTX2更新软件源

    JestonTX2刷机后需要更新软件源 更新软件源后 xff0c 才可以正常安装QT等软件 软件源记录文件放在以下文件中 cd etc apt source list 可以使用gedit打开此文件 sudo gedit etc apt so
  • Kali的下载安装详细过程

    1 什么是Kali xff1f Kali Linux是专门用于渗透测试的Linux操作系统 2 打开官网 Kali Linux Penetration Testing and Ethical Hacking Linux Distributi
  • 本地搭建GitLab地址不一致问题

    1 本地虚拟机用docker搭建Gitlab project clone 地址如下 xff1a 实际地址如下 xff1a http 192 168 56 51 root apacha backend 本来没在意这个问题 xff0c clon
  • 数据库笔试题(答案)

    一 填空题 每题2分 xff0c 共10分 1 索引字段值不唯一 xff0c 应该 使用 的索引类型为 普通索引 2 只有满足联接条件的记录才包含在查询结果中 xff0c 这种联接为 内联接 3 E R模型的组成包括那些 元素 实体 属性
  • mac时间机器占用大量系统盘空间且在访达中无法找到

    mac用时间机器备份到外置移动硬盘 xff0c 但是后来发现mac系统盘占用随之增加 经过研究发现 xff0c 时间机器备份是现在mac系统盘备份然后转移到移动硬盘 xff0c 而且系统盘中的备份文件是隐藏的 xff0c 所以在关于本机 x
  • android——降低gradle的版本、下载好gradle的包存放的位置

    一 降低gradle的版本 本文以gradle版本7 0 2改成6 3为例子 xff1a 1 在build gradle里面修改dependencies里面的 classpath 34 com android tools build gra
  • C语言十进制转八进制、十六进制以及十六进制转十进制、八进制

    以下程序的输出结果是 main int a 61 20 printf 34 d o x n 34 a a a 看到这个题目首先我们要明白 o 和 x代表的是什么意思 o代表的是输出该数字的八进制 x代表的是输出该数字的十六进制 1 题目给出
  • 解决Mybatis分页插件PageHelper自动添加limit导致分页失败问题

    目录 1 问题描述2 解决方案2 1 方案一2 2 方案二 3 完成效果4 一点困惑5 参考文献 1 问题描述 今天在完善项目的时候 xff0c 有一个需求就是给我的评论区实现分页显示评论数 xff0c 但是当自己运行的时候点击查看评论的时
  • STM32 HAL库 STM32CubeMX -- I2C(IIC)

    文章目录 一 I2C 协议简介I2C 物理层I2C协议层I2C架构通讯过程 二 STM32Cube MX配置三 I2C HAL库函数 一 I2C 协议简介 I2C 通讯协议 Inter xff0d Integrated Circuit 也就
  • 一个unsigned int 数的二进制表示中有多少个1

    这是一道面试题可以用以下的一些方案 第一种是很容易想到的采用循环的方式并且与1进行位与运算 xff0c 具体代码如下 1 unsigned int GetBitNumOfOne ByLoop1 unsigned int nValue 2 3