求一个数二进制表示法中1的个数诸多方法 .

2023-05-16

求一个unsigned int 数的二进制表示中有多少个1?
这是一道面试题可以用以下的一些方案。
第一种是很容易想到的采用循环的方式并且与1进行位与运算,具体代码如下。

unsigned int GetBitNumOfOne_ByLoop1(unsigned int nValue)
{
	const unsigned int nNumOfBitInByte = 8;
	unsigned int nBitMask = 1;
	unsigned int nBitNum = 0;
	for(unsigned int i = 0 ; i < sizeof(nValue) * nNumOfBitInByte ; i++)
	{
		(0 < (nValue & nBitMask)) ? nBitNum++ : 0;
		nBitMask<<=1;
	}
	return nBitNum;
}


 

unsigned int GetBitNumOfOne_ByLoop2(unsigned int nValue)
{
	const unsigned int nNumOfBitInByte = 8;
	unsigned int nBitMask = 1;
	unsigned int nBitNum = 0;
	for(unsigned int i = 0 ; i < sizeof(nValue) * nNumOfBitInByte ; i++)
	{
		(0 < (nValue & nBitMask)) ? nBitNum++ : 0;
		nValue>>=1;
	}
	return nBitNum;
}


这两种做法很相像,却别就是在是对nBitMask进行左移还是对nValue进行右移。
当然了以上的两个方法存在一个问题:不管如何这个函数肯定要循环32次(对于32平台来说)。
那又没有更好的方法?当然有,请看下面:

unsigned int GetBitNumOfOne_ByLoop3(unsigned int nValue)
{
	unsigned int nBitNum = 0;
	while(0 < nValue)
	{
		nValue &=(nValue - 1);
		nBitNum++;
	}
	return nBitNum;
}


假如使用参数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的个数。
上面的做法已经很不错了,但是作为程序员的你是否会有疑问,"还有其他的方法吗?"。
有,当然有!请看下面的代码:

unsigned int GetBitNumOfOne(unsigned int nValue)
{
	nValue = ((0xaaaaaaaa & nValue)>>1) + (0x55555555 & nValue);
	nValue = ((0xcccccccc & nValue)>>2) + (0x33333333 & nValue);
	nValue = ((0xf0f0f0f0 & nValue)>>4) + (0x0f0f0f0f & nValue);
	nValue = ((0xff00ff00 & nValue)>>8) + (0x00ff00ff & nValue);
	nValue = ((0xffff0000 & nValue)>>16) + (0x0000ffff & nValue);
	return nValue;
}


假如你是第一次看到这些代码,你是否能看明白?呵呵,本人第一次看到这些代码的时候看了好久才感觉
好像有点明白。下面我就以一个例子来说明上面的代码是如何做到的。
假如参数是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(使用前将#替换为@)

求一个数二进制表示法中1的个数诸多方法 . 的相关文章

  • IP网络性能测试工具——Renix Perf

    一 Renix Perf 基于软件的网络及应用服务性能测试工具 双臂测试 单臂测试 通过测试端点产生网络流量对网络性能进行测量 TCP UDP PING 语音 视频 HTTP FTP MAIL 组播 测试端点软件可以免费安装部署 二 部署方
  • 网络测试技术——802.1X_MD5认证(下篇)

    上篇我们讲到802 1X MD5的简介 认证过程 测试组网以及测试环境准备 xff0c 本期我们将为大家带来测试的详细步骤 xff1a 六 测试仪配置 1 占用端口 端口功能 xff08 1 xff09 端口1用来模拟DOT1X和发送流量
  • 网络测试技术——802.1X TLS认证(上篇)

    一 TLS认证简介 1 TLS认证 xff08 1 xff09 认证过程 最安全认证技术 实施最复杂 xff08 2 xff09 TLS双向证书认证 服务器对客户端进行认证 客户端对服务器进行认证 2 TLS认证过程 3 交换机认证模式 x
  • SRv6测试技术简介

    什么是SRv6 xff1f SRv6技术就是采用现有的IPv6转发技术 xff0c 通过扩展IPv6报文的头域 xff0c 实现类似标签转发的处理 SRv6将一些IPv6地址定义成实例化的SID xff08 Segment ID xff09
  • RENIX 软件RAW流发送——网络测试仪实操

    本文主要介绍了RENIX软件如何进行RAW流发送操作 文章通过预约端口 添加RAW流 修改负载 发送流量 查看流统计 数据包捕获六个步骤详细介绍了操作过程 步骤一 xff1a 预约端口 1 先安装RENIX软件 xff0c 正确安装情况下桌
  • RENIX软件OSPF和BFD、ISIS和BFD联动测试——网络测试仪实操

    本文介绍了RENIX软件BFD测试相关操作 xff0c 全文分为五大部分 第一部分为BFD概述 xff1b 第二部分为搭建OSPF和BFD联动测试环境 xff1b 第三部分为OSPF和BFD联动测试配置 xff1b 第四部分为搭建ISIS和
  • 信而泰 X-Snapper测试系统,助力家庭路由器IPv6支持度测试

    随着互联网的蓬勃发展 xff0c 宝贵而有限的IPv4地址资源一直在被分配使用 2019年11月25日 xff0c 负责英国 欧洲 中东和部分中亚地区互联网资源分配的欧洲网络协调中心 xff08 RIPE NCC xff09 宣布 xff0
  • 如何使用测试仪进行400G交换机性能测试

    一 400G以太网概述 400G以太网或400 Gigabit Ethernet 400GbE 由 IEEE P802 3bs Task Force 于 2017 年开发 xff0c 它使用与100 Gigabit Ethernet 大致相
  • 【python3】简易双因子Radius认证服务器,带UI界面

    需要将dictionary rfc2865放在运行的同级目录下 coding utf 8 from tkinter import from tkinter ttk import from tkinter import scrolledtex
  • 信而泰测试方案,助力客户打造网络安全防护“金钟罩”

    一 网络安全行业面临的挑战 据 Cybercrime Magazine 在最近一份报告中称 xff0c 仅2021年 xff0c 黑客攻击和各种网络犯罪就给全球经济造成了超过6万亿美元的损失 xff0c 预计到2025年 xff0c 此类犯
  • BGP BFD测试案例

    一 BFD原理 1 1 BFD技术简介 一种全网统一 检测迅速 监控网络中链路或者IP路由的双向转发连通状况 xff0c 并未上层应用提供服务的技术 1 2 BFD会话建立方式和监测机制 BFD的标识符 xff1a xff08 1 xff0
  • 数据中心典型测试场景浅析

    数据中心概述 数据中心泛指拥有众多服务器的大型机房 xff0c 通过利用通信运营商已有的互联网通信线路 带宽资源 xff0c 建立标准化的数据中心机房环境 xff0c 具有运行速度快 存储量大 安全性高等特点 数据中心东西向流量的占比更大
  • Vxlan协议原理及基本配置——网络测试仪实操手册

    一 Vxlan协议原理 1 Vxlan协议相关术语 一 缩略语 OSI中的概念 NVE Network Virtualization Edge 网络虚拟边缘节点 VTEP VXLAN Tunnel Endpoints xff0c VXLAN
  • 如何模拟VTEP下大量VM主机ARP消息——网络测试仪实操

    模拟VTEP下大量VM主机ARP消息 xff0c 按照下面的步骤 xff1a 1 打开 Renix 软件 xff0c 连接机框并预约测试端口 xff1b 2 创建一条RAW流量 xff08 Binding流量也可以 xff0c 这里用RAW
  • 信而泰自动化OSPFv2测试小技巧

    OSPFv2协议简介 OSPFv2 xff08 开放式最短路径优先版本2 xff09 是互联网协议 xff08 IP xff09 网络的路由协议 它使用链路状态路由 xff08 LSR xff09 算法 xff0c 并且属于在单个自治系统
  • OpenFlow协议原理及基本配置-网络测试仪实操

    一 OpenFlow协议原理 1 OpenFlow技术背景 转发和控制分离是SDN网络的本质特点之一 在SDN网络架构中 xff0c 控制平面与转发平面分离 xff0c 网络的管理和状态在逻辑上集中到一起 xff0c 底层的网络基础从应用中
  • 如何使用向导创建Openflow 流表-网络测试仪实操

    使用向导创建Openflow中的FlowTable xff0c 按照下面的步骤 xff1a 1 打开Renix软件 xff0c 连接机框并预约测试端口 xff1b 2 配置一个IPv4接口 3 配置一个OpenFlowController绑
  • 信而泰OLT使用介绍-网络测试仪实操

    一 OLT产品介绍 1 概述 PON作为FTTX网络发展的核心技术 xff0c 局端设备OLT尤其重要 本文档中主要介绍OLT的功能特性 业务配置 2 基本功能特性 2 1大容量和高集成度 ZXA10 C300集光接入 数据交换 路由处理于
  • 信而泰耦合测试-网络测试仪实操

    一 耦合测试原理 1 产生背景 常用测试无线设备过程中 xff0c 将无线设备置于屏蔽箱中 xff0c 通过无线网卡连接并运行iperf等类似软件的方式检测所述无线设备的吞吐量 相关技术中将所述无线设备置于所述屏蔽箱中的检测方法 xff0c

随机推荐

  • 【python】程序绑定PC和时间戳做定期授权码

    取磁盘编码或者网卡编码 43 时间戳16位格式 关于时间戳 xff0c 当前简单的实现是年月日转成对应的16位 xff0c 比如 23 03 28 gt 173E xff08 日先直接整除2 xff0c 每月不会超过31天 xff0c 整除
  • 信而泰ALPS 用户管理——网络测试仪实操

    本文介绍了如何在ALPS平台上Step By Step进行用户管理 用户管理介绍 设备在出厂时 xff0c 提供了一个默认管理员账号 xff0c 该账号为admin admin 管理员账号除了可用于测试之外 xff0c 还具有用户管理权限
  • 信而泰RENIX 802.1ag功能介绍-网络测试仪实操

    一 EOAM概述 1 以太网 1 1以太网优点 简单易用 价格低廉 高拓展性 大势所趋 xff0c 一统天下 1 2以太网缺点 可管理性差 定位故障手段少 定位故障速度慢 维护成本高 2 以太网OAM EOAM 为运营商服务 提高以太网可靠
  • 信而泰BGP Flow Spec防攻击测试解决方案

    随着互联网行业的迅猛发展 xff0c 越来越多的业务都从线下走到了线上 互联网在给大家生活带来便利的同时也面临着防护自身安全的各种挑战 DoS DDoS攻击是对网络安全的重大威胁 xff0c 攻击者通过多个控制端控制成千上万的攻击设备对同一
  • 信而泰X1多速率板卡写入SN号和ID——网络测试仪实操

    一 X1多速率板卡SN号和ID说明 速率的License文件需要根据板卡SN号和ID来制作 3 1 6正式版本 xff0c DarYu L2 7高性能 网络测试仪 支持用户通过Renix查看板卡SN号号 但是有的板卡可能存在没有SN号和ID
  • renix如何查看时延和抖动和丢包——网络测试仪实操

    目录 查看时延和抖动 一 预约测试资源 二 新建流 三 查看时延和抖动 查看丢包 一 预约端口 二 创建Raw流 三 如何查看流量的实时丢包个数和丢包比例 查看时延和抖动 一 预约测试资源 打开Renix软件 xff0c 连接机箱 预约端口
  • IP 网络主动监测系统 Renix Active

    一 IT网络运维面临的挑战 1 网络性能可视化 与公有云和SaaS平台连接的可靠性 广域网线路性能 互联网专线性能 2 诊断工具 现场无IT工程师覆盖 诊断的人力费用 网络与应用系统的纠结 3 用户体验 Web应用的访问质量 语音语音视频的
  • FEC原理与操作及BigTao机框装机说明

    一 FEC原理与操作 1 FEC 原理简介 前向纠错 xff08 英语 xff1a forward error correction xff0c 缩写FEC xff09 或信道编码 xff08 英语 xff1a channel coding
  • 信而泰RENIX时延抖动原理和计算公式、流量“重复次数”的使用、通道的作用

    一 信而泰Renix时延抖动原理和计算公式 信而泰RENIX时延抖动原理和计算公式 流量 重复次数 的使用 通道的作用 1 时延抖动原理 时延抖动是网络监视和测量的一个重要指标 在VoIP或视频流中 xff0c 数据包以连续流的形式发送 x
  • 从单体式架构迁移到微服务架构

    迁移到微服务综述 迁移单体式应用到微服务架构意味着一系列现代化过程 xff0c 有点像这几代开发者一直在做的事情 xff0c 实时上 xff0c 当迁移时 xff0c 我们可以重用一些想法 一个策略是 xff1a 不要大规模 xff08 b
  • boost库编译参数小结

    编译boost库 32位编译 xff1a 从开始菜单启动Visual Studio 2013的vs2013 命令行 xff0c 进入boost所在目录 xff0c 运行bootstrap bat 编译命令 xff08 例 xff09 xff
  • 【python】动态运行py文件并生成exe可执行程序

    main py if name 61 61 39 main 39 if len sys argv gt 1 file path 61 sys argv 1 check folder 61 os path dirname file path
  • 麒麟V10 root登录系统

    麒麟V10 root登录系统 提示 xff1a 麒麟V10桌面操作系统 xff0c 安全性考虑不允许root登录的 一 root登录界的图片 root登录界面如图所示 xff0c 需要手动输入用户名和密码 二 使用步骤 1 设置root密码
  • ALTIUM_ROOM格式复制

    特别注意通道号要对应相同 1 D M T 从选择的器件产生矩形的ROOM 2 如图 xff1a 3 4 D M C 先后点击参照布局和未布局 5 设置如下 6 点击确定即可
  • Chrome的Cookie的存放位置及查看方法

    Chrome的Cookie存放位置 C Users xxx AppData Local Google Chrome User Data Default Cookies实际上是一个sqlite数据库文件 可以直接打开查看 Cookie的解密参
  • C# 输入指定日期获取当前年的第一天 、当前年的最后天、某月的第一天 、某月的最后一天...

    方法 lt summary gt 取得当前年的第一天 lt summary gt lt param name 61 34 datetime 34 gt 要取得月份第一天的时间 lt param gt lt returns gt lt ret
  • centos7 和 ubuntu 安装xrdp

    centos7 和 ubuntu 安装xrdp centos7安装xrdp问题1 xrdp 找不到 ubuntu 的安装 centos7安装xrdp span class token comment 安装软件 span yum span c
  • centos7安装xrdp

    centos7安装xrdp 保证有桌面环境安装epel安装xrdp配置xrdp 保证有桌面环境 yum y span class token function groups span span class token function in
  • 在vs2017中遇到“fatal error RC1015: cannot open include file 'winres.h'.”

    解决方法 xff1a 先查找winres h所在位置 xff0c 将文件的目录位置添加到属性 VC 43 43 目录 包含目录中 xff0c 即可 类似问题亦可
  • 求一个数二进制表示法中1的个数诸多方法 .

    求一个unsigned int 数的二进制表示中有多少个1 xff1f 这是一道面试题可以用以下的一些方案 第一种是很容易想到的采用循环的方式并且与1进行位与运算 xff0c 具体代码如下 unsigned int GetBitNumOfO