> 文档中心 > Python每日一练-----位1的个数

Python每日一练-----位1的个数

(day33)

目录

📝题目:

🚩题目分析:

💡解题思路:

常规解法:✏

🌈代码实现

位运算解法:✏

🌈代码实现


📝题目:

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量)。(输入必须是长度为 32 的 二进制串 )

⭐示例 1:

输入:00000000000000000000000000001011
输出:3
解释说明:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

⭐示例 2:

输入:00000000000000000000000010000000
输出:1
解释说明:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

⭐示例 3:

输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

🚩题目分析:

比较简单的计数问题,寻找二进制数中1的个数。

💡解题思路:

常规解法:✏

对于传入的二进制数,函数在接受二进制数时二进制数n表示成0b.......

在python中

  • 0b或0B表示二进制
  • 0o或0O表示八进制
  • 0x或0X表示十六进制

(第一位的0表示数字零,第二位表示字母)

我们想知道二进制数中含有1的数目,那么我们需要遍历该二进制数,但是我在其他文章也常写到的问题就是数值是不可以直接遍历的,所以我们可以将其转换为字符串,因为字符串可以遍历。

那么我们如何将该二进制数转换成字符串?

转换成字符串我们常用的是str()函数,然而如果使用str()函数将二进制数转换成字符串时str()函数会自动将二进制数转换成十进制,这会影响我们判断1的个数

📖-------------------------------------------

n = 0B00000000000000000000000000001011(=11,十进制数)

m = str(n)

print(m)

print(type(m))

输出:

11                   

----------------------------------

这时我们还要需要将十进制数转换成二进制数。

但python有个内置的函数bin()可以直接将二进制数转换成十进制数,bin()函数会将二进制略写

📖-------------------------------------

n = 0B00000000000000000000000000001011

m = bin(n)

print(m)

print(type(m))

输出:

0B1011            

------------------------------------

解决了数值不能直接遍历问题,我们可以直接进行遍历

🌈代码实现

def hammingWeight(n):    n = bin(n)    answer = 0    for i in range(2, len(n)): if int(n[i]) == 1:     answer += 1    return answer

这里的 i 为什么从2开始呢?

我们注意到bin()函数将二进制转换位字符串时会把进制标识符0B输出,但它仅表示进制,所以可以不用遍历它们,i就可以从2开始。

 (这是计算速度超过97%的算法)

位运算解法:✏

位运算的骚操作

我们可以只用位运算构造一个“检测器”,这个检测器检测原理同遍历一样,它从右到左一个个遍历并判断该位置上的数是否为1

我们暂停抽线的描述,先看代码

🌈代码实现

def hammingWeight(n):    a, ans = 0, 0    while a <= 32: if (1 << a) & n != 0:     ans += 1 a += 1    return ans

可以看出位运算的“检测器”就是(1 << a) & n != 0

(不清楚位运算的学请点这里:还在为原码、反码、补码和位运算搞得头昏脑涨?点这里,还你清析脑回路

为了写位运算的题解特意写的)

1对应的三十二位二进制为:00000000000000000000000000000001

a初始值为0,当1<<0,1的二进制不进行右移,00000000000000000000000000000001与n进行按位与&运算,因为只有1&1=1,这是我们将计数器ans+1.

如果按位与运算结果为0,说明n的二进制数对应的位置上没有1.我们将a加1,1<<a就会将00000000000000000000000000000001末尾的1往后移a位,这样我们就可以实现n的遍历。

由于题目说民n的最大位数位32位,所以while循环结束的条件设置位 a<<32即可

(这是数据显示计算速度超过99%的解法)

今天就到这,明天见。🚀

❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄

书法艺术字体