首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

计数二进制表示的1的个数

基础概念

计数二进制表示的1的个数,通常称为“位运算”中的“计算汉明重量”(Hamming Weight)。汉明重量是指一个数的二进制表示中1的个数。这个操作在计算机科学中非常常见,尤其是在位操作、网络通信、加密算法等领域。

相关优势

  1. 高效性:位运算通常比算术运算更快,因为它们直接操作二进制位。
  2. 节省空间:位运算可以用来压缩数据,减少存储空间。
  3. 灵活性:位运算可以用来实现各种复杂的逻辑操作。

类型

  1. 直接计数法:遍历二进制表示的每一位,统计1的个数。
  2. 位运算法:利用位运算的特性来高效地计算1的个数。

应用场景

  1. 网络通信:在IP地址和子网掩码的计算中,经常需要统计二进制表示中1的个数。
  2. 加密算法:在某些加密算法中,需要对数据进行位操作,统计1的个数是一个常见的步骤。
  3. 性能优化:在编写高效的代码时,位运算可以帮助提高程序的性能。

示例代码

以下是一个用Python实现的计算汉明重量的函数:

代码语言:txt
复制
def hamming_weight(n: int) -> int:
    count = 0
    while n:
        count += n & 1
        n >>= 1
    return count

# 示例
num = 0b00000000000000000000000000001011
print(hamming_weight(num))  # 输出: 3

参考链接

常见问题及解决方法

问题:为什么直接计数法效率较低?

原因:直接计数法需要遍历每一位,时间复杂度为O(log n),其中n是数字的大小。

解决方法:使用位运算法可以提高效率。例如,通过n & (n - 1)可以快速去除最低位的1。

代码语言:txt
复制
def hamming_weight_bitwise(n: int) -> int:
    count = 0
    while n:
        n &= n - 1
        count += 1
    return count

# 示例
num = 0b00000000000000000000000000001011
print(hamming_weight_bitwise(num))  # 输出: 3

问题:在某些情况下,位运算可能会导致溢出,如何解决?

原因:当处理大整数时,位运算可能会导致溢出。

解决方法:使用Python等支持大整数的编程语言,或者在处理大整数时,分块进行位运算。

代码语言:txt
复制
def hamming_weight_large_number(n: int) -> int:
    count = 0
    while n:
        n &= n - 1
        count += 1
    return count

# 示例
num = 0b11111111111111111111111111111101
print(hamming_weight_large_number(num))  # 输出: 31

通过上述方法,可以高效地计算二进制表示中1的个数,并解决常见的位运算问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

输出该数二进制表示1个数

题目:输入一个整数,输出该数二进制表示1个数。其中负数用补码表示。...如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边1就会变为0,原来在1后面的所有的0都会变成1(如果最右边1后面还有0的话)。...举个例子:一个二进制数1100,从右边数起第三位是处于最右边一个1。...减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到结果是1011.我们发现减1结果是把最右边一个1开始所有位都取反了。...如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数二进制有多少个1,就可以进行多少次这样操作。

54820

二进制1个数

1个数。...分析 在解决这个问题之前,我们先来分析这样一个场景: 如果一个整数不等于0,那么该整数二进制表示中至少有一位是1。 先假设这个数最右边一位是1,那么减去1时,最后一位变成0而其他所有位都保持不变。...接下来,假设这个数最右边一位是0情况: 如果该整数二进制表示中,最右边1,位于第m位,那么减去1时: 第m位由1变成了0 第m位之后所有0都变成1 整数中第m位之前所有位都保持不变 我们举个例子...那么,一个整数二进制表示中有多少个1,就可以进行多少次这样操作,直至整个数变为0,我们对每一次操作进行计数,就得到了这个问题答案。...、BinaryOperation-test.ts 运行结果与我们手动算出来二进制数中1个数一致 -80我们在前面的章节中算过它二进制表示为10110000,我们讲过二进制具体在计算机中占多少位,取决于它字长

76320
  • 二进制1个数

    题目描述 输入一个整数,输出该数二进制表示1个数。其中负数用补码表示。 解题思路 如果一个整数不为0,那么这个整数至少有一位是1。...如果我们把这个整数减1,那么原来处在整数最右边1就会变为0,原来在1后面的所有的0都会变成1(如果最右边1后面还有0的话)。其余所有位将不会受到影响。...举个例子:一个二进制数1100,从右边数起第三位是处于最右边一个1。...减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到结果是1011.我们发现减1结果是把最右边一个1开始所有位都取反了。...如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数二进制有多少个1,就可以进行多少次这样操作。

    61120

    二进制1个数

    输入一个整数,输出该数二进制表示1个数。其中负数用补码表示。 解析:如果一个整数不为0,那么这个整数至少有一位是1。...如果我们把这个整数减1,那么原来处在整数最右边1就会变为0,原来在1后面的所有的0都会变成1(如果最右边1后面还有0的话)。其余所有位将不会受到影响。...举个例子:一个二进制数1100,从右边数起第三位是处于最右边一个1。...减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到结果是1011.我们发现减1结果是把最右边一个1开始所有位都取反了。...如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数二进制有多少个1,就可以进行多少次这样操作。

    55820

    计算二进制1个数

    在计算机里,一个int整型数据二进制最多有32位,想要统计里面的1个数,最基本思路就是让n对2求余(基于10进制转换为二进制方法)等于1,并实现累加。...第二种方法:遍历二进制位数 开头提到,对于32位二进制数,如果直接遍历来计数1的话会更加方便,具体操作如下: 这里会用到&(按位与)和>>(右移操作符)进行实现,从最低位开始,每一位都和1按位与(同1...为1,异1为0)并进行判断计数,完成后左移一位,既然有32位,就循环32次,重述上述操作。...举个例子,我们用一个循环来让n与n-1按位与,n设为15,二进制为1111,n-1=14=1110,这时候按位与,我们发现,1111&1110=1110,得到值与15相比少了11,那可不可以将这个1...循环结束,我们发现,减少1个数刚好是15二进制1个数,同时也等于循环次数,极大提高了效率。

    12610

    二进制1个数_11

    输入一个整数,输出该数32位二进制表示1个数。其中负数用补码表示。 输入10 返回2 //思路: 如果一个整数不为0,那么这个整数至少有一位是1。...如果我们把这个整数减1,那么原来处在整数最右边1就会变为0,原来在1后面的所有的0都会变成1(如果最右边1后面还有0的话)。其余所有位将不会受到影响。...而我们用原来数字和减1数字做与运算后,原来最后右边1和后面的数就都会变为0 如 12二进制1100 1100 -1 =1011 1100&1011=1000 这就是一次完整运算 如果我们继续...1000 -1 =0111 1000 &0111=0000 每次消除最右边一个0,几次运算就有几个0 public int NumberOf1(int n) { int count...=0){ count++; //这里做与运算正好可以把原本最右边1后面的0都给去掉 //1 1 0 0 & 1 0 1 1=10000

    22910

    二进制或负数补码中 ‘1个数

    题目描述: 输入一个整数,输出该数二进制表示1个数。其中负数用补码表示。...---- 整数二进制求法: 十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinaryString...(int i) 这3个函数都可以将十进制整数转换成二、一六、八进制数 不过转换后结果都是字符串形式 ---- 负数( 32位 )补码: 思路:求负数补码方法。...注意: 负数补码是在其原码基础上,符号位不变,其余位取反,然后加1 ---- 代码: public class Solution { private int num; private boolean...其余位数为0整数 int t = (a & 0x80000000 >>> i) >>> (31 - i); if (t == 1) { num++;

    59430

    统计一个数二进制1个数

    最近一个需求需要使用golang实现一个兼容redis无压缩bitmap,需要提供一个bitcoun函数来统计这个bitmap中二进制1个数,查了一圈并没有找到类似的第三方库,因此决定自己实现一个...问题简化 问题本质实际就是给定一个数字,比如一个二进制数10101101,计算出这个数字中二进制1个数,对于10101101这个数字来说它有5个位为1,即:10101101 对于这个问题,最简单办法就是挨位数...3.1 2位数字二进制1个数 我们先想一下如何计算2位数字二进制1个数,答案是非常简单: func OnesCount2(x uint2) int { return (x & 0b01...) + ((x >> 1) & 0b01) } x & 0b01就是求第0位是不是1,((x >> 1) & 0b01)就是求第1位是不是1,加起来就是x这个2位数字二进制1个数。...3.2 4位数字二进制1个数 对于一个4位数字,如1011,我们先按照3.1中算法分别求出第3位与第2位即10 和 第1位与第0位即11二进制1个数,然后再加起来就得出这个4位数字二进制

    10110

    剑指Offer(十一)--二进制1个数

    题目描述 思路以及解法 题目描述 输入一个整数,输出该数32位二进制表示1个数。其中负数用补码表示。 思路以及解法 首先说一个错误解法,很多人可能会想到,那就是不断对2取余数。...但是这种做法有个致命缺陷,那就是忽略了负数,负数使用补码表示时候,是取反之后加一,而且 public class Solution { public int NumberOf1(int n)...} return num; } } 其次就是移位算法,把整数当成二进制,不断向右移位和1进行与计算。...还有一种做法不断把最右边1变成0,那就是利用n=n&(n-1),比如7二进制是111,那么7&6=111&110=110=6,就完美把最后一位1变成0了,6二进制是110,6&5=110&101...javaapi把整数,转成字符串,遍历一次获取1个数,可以但是不提倡,因为本题考查是位运算,而不是api使用和for循环。

    20520

    二进制1 个数

    题目汇总链接:https://www.algomooc.com/hi-offer 一、题目描述 请实现一个函数,输入一个整数,输出该数二进制表示1 个数。...例如,把 9 表示二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。...二进制1个数.008 ? 二进制1个数.008 ? 二进制1个数.010 ? 二进制1个数.011 ? 二进制1个数.012 ? 二进制1个数.013 ?...二进制1个数.014 ? 二进制1个数.015 ? 二进制1个数.016 ? 二进制1个数.017 ? 二进制1个数.018 ? 二进制1个数.019 ?...二进制1个数.020 ? 二进制1个数.021 ? 二进制1个数.022 ? 二进制1个数.023 ? 二进制1个数.024 ? 二进制1个数.025 ?

    42640

    剑指offer--二进制1个数

    题目描述 输入一个整数,输出该数二进制表示1个数。...其中负数用补码表示 Java代码: public class Solution { public int NumberOf1(int n) { String binary = Integer.toBinaryString...第一种:让n与1相与后判断是否为真,若为真,计数器cnt加一并将n右移1位直至n为0。这种思路受限于n是否为正数,若n为负数,那么每次右移最高位补1而非0,那么这会导致死循环。...第三种:一个数n如果减1,那么将这个2进制数从右向左第一个“1”变成0,若这个1不是最低位,那么之后所有位取反,而这个1左边所有位保持不变。...那么n与n-1相与可以使从右向左第一个1与其之后位变成0,那么这个2进制数有几个1,只需几次上述操作即可。

    29910
    领券