Python统计二进制中1的个数

应用案例

现有一个整数,将该整数转化为二进制形式,并统计二进制中1的个数(如果是负数,按补码统计1的个数)

涉及知识点讲解

进制介绍

在计算机中,有四种进制,分别是 2进制、8进制、10进制和16进制。具体内容如下所示:

进制类型 组成 代码格式
2进制 由2个数字组成,有0 和 1 0b101
8进制 由8个数字组成,有0,1,2,3,4,5,6,7 0o127
10进制 有10个数字组成,有0,1,2,3,4,5,6,7,8,9 258
16进制 有16个数字组成,有0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f (字母不区分大小写, a至f分别代表10,11,12,13,14,15) 0xff、0Xff、0XFF

进制转换

Python中常用的内置进制转换函数如下所示:

  1. bin(x): 将 x 转换为2进制;
  2. oct(x): 将 x 转换为8进制;
  3. int(x, base=10): 将 x 转为 10 进制;
  4. hex(x): 将 x 转为 16 进制;

原码、反码、补码介绍

计算机使用一定的编码方式对数据进行存储。原码、反码、补码是机器存储一个具体数字的编码方式。具体使用方式整理如下:

  1. 正数的原码、反码、补码都相同;
  2. 负数的反码在原码的基础上保持符号位不变,其余位取反;
  3. 负数的补码在反码的基础上+1;

eg:

+1 -1
原码 0000 0001 1000 0001
反码 0000 0001 1111 1110
补码 0000 0001 1111 1111

位运算规则

含义 Python表示 规则说明
按位与 a & b 同时为1,则为1
按位或 a | b 有1则为1
按位异或 a ^ b 相同为0,不同为1
按位取反 ~a 0变1,1变0
左移 a << b a × 2**b
右移 a >> b a / 2**b

解法1

思路分析

首先需将整数转换成二进制,转换时考虑正整数和负整数两种情况:

  • 如果是正整数,直接转换成二进制即可;
  • 如果是负整数,需求出该数对应的补码,以便后期解题;

难点:Python中如何让对一个负整数求补码?

等全部转换成二进制后,开始统计1的个数,解法1为:将该二进制数转化为字符串,然后对该字符串进行遍历,如果等于1,计数器+1;

代码实现

def oneCount1(n):
    # 使用Python内置bin函数转化成二进制;
    print(bin(n))
    if n < 0:
        # 下一行语句是 按位与运算求一个负数的补码
        # 表示先将符号两边转换成二进制,再进行与运算
        # “与运算”的规则是:同时为 1;则为 1
        # 返回结果是十进制,将与运算后的二进制转化的十进制
        # 此处的 0xffffffff中的 0x 表示16进制,1个f代表4个1。
        # 整体解释为 2进制的 32个1;
        n = n & 0xffffffff
        print(n)
    print(bin(n))
    
    # 将2进制数转化为一个字符串,去除前两位"ob"
    bin2 = str(bin(n))[2:]
    print(bin2)
    count = 0
    for i in str(bin2):
        if i == '1':
            count += 1
    return count

print(oneCount1(12))
print(oneCount1(-12))

执行结果如下所示:

0b1100
0b1100
1100
2

-0b1100
4294967284
0b11111111111111111111111111110100
11111111111111111111111111110100
29

解法2

思路分析

解法2的前半步和解法1相同,即先将一个整数转化成一个二进制数;

利用”按位与“的方法,取各个位上的数字,判断如果等于0,计数器+1,反之跳过;

代码实现

def oneCount2(n):
    print(bin(n))
    if n < 0:
        n = n & 0xffffffff
        print(n)
    print(bin(n))

    m = len(bin(n)) - 2
    count = 0
    for i in range(0, m):
        """
        1101 = 13
                   &
        0001 = 1  0001  count++
        0010 = 2  0000
        0100 = 4  0100  count++
        1000 = 8  1000  conut++  
       
        """
        if n & 2 ** i != 0:
            count += 1
    return count

print(oneCount2(13))
print(oneCount2(-13))

执行结果如下:

0b1101
0b1101
3

-0b1101
4294967283
0b11111111111111111111111111110011
30
发布了21 篇原创文章 · 获赞 6 · 访问量 7999

猜你喜欢

转载自blog.csdn.net/weixin_42128329/article/details/104310565