• 位运算及其应用


    位运算

    <<	按位左移,左移n位相当于乘以2的n次方
    >>	按位右移 ,右移n位相当于除以2的n次方
    &	按位与,二进制位数同且为1结果位为1
    |	按位或 ,二进制位数或有1结果位为1
    ^	按位异或 ,二进制位数不同结果位为1
    ~	按位取反,二进制位0和1结果位互换
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    print(1<<3)#输出8:       1*2^3=8
    
    • 1

    n & (n−1),其运算结果恰为把 n 的二进制位中的最低位的 1变为 0 之后的结果。
    如:6&(6-1) = 4, 6 = (110), 4 = (100),6 & (6−1)=4;运算结果 4 即为把 6 的二进制位中的最低位的 1变为 0 之后的结果。
    n & 1等价于n%2==1,n的二进制位中的最低位如果是1,则返回1,否则返回0,可用于奇偶的判断。
    如:3&1=1,2&1=0

    (num >> i) & 1,用于获取一个数值 num 的第 i 位的值。

    ans |= (1 << i)是一种常见的位操作技巧,将ans(初始ans=0)的第i位设置为1,其他位保持不变。
    (1 << i) 这一部分创建了一个只有第i位是1,其余位都是0的二进制数。这是通过将1左移i位得到的结果。
    “|=” 是一个复合赋值运算符,用于将按位或的结果与左侧的变量进行逻辑或运算,并将结果赋值给左侧的变量。因此,“ans |= (1 << i)” 表示将ans的第i位设置为1,而不影响其他位。

    异或

    n为偶数时,n^1=n+1;n为奇数时,n^1=n-1
    任何数和 0做异或运算,结果仍然是原来的数,即 n^0=n
    任何数和其自身做异或运算,结果是 0,即n^n=0
    异或运算满足交换律和结合律。

    位运算的应用举例1

    两个数不使用四则运算得出和:(按位异或的应用)

    8 ^ 7 # 1000 ^ 0111 -> 1111 -> 15
    8 ^ 8 # 1000 ^ 1000 -> 0000 -> 0
    
    • 1
    • 2

    因为按位异或就是不进位加法,8 ^ 8 = 0 如果进位了,就是 16 了,所以我们只需要将两个数进行异或操作,然后进位。那么也就是说两个二进制都是 1 的位置,左边应该有一个进位 1,所以可以得出以下公式 a + b = (a ^ b) + ((a & b) << 1)

    位运算的应用举例2

    191. 位1的个数
    编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
    示例 1:

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

    示例 2:

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

    class Solution:
        def hammingWeight(self, n: int) -> int:
            #方法1
            # return str(bin(n)).count('1')
            #方法2
            ret = 0
            while n:
                n &= n - 1
                ret += 1
            return ret
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    位运算的应用举例3

    868. 二进制间距
    给定一个正整数 n,找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1,返回 0 。

    如果只有 0 将两个 1 分隔开(可能不存在 0 ),则认为这两个 1 彼此 相邻 。两个 1 之间的距离是它们的二进制表示中位置的绝对差。例如,“1001” 中的两个 1 的距离为 3 。

    示例 1:

    输入:n = 22
    输出:2
    解释:22 的二进制是 “10110” 。
    在 22 的二进制表示中,有三个 1,组成两对相邻的 1 。
    第一对相邻的 1 中,两个 1 之间的距离为 2 。
    第二对相邻的 1 中,两个 1 之间的距离为 1 。
    答案取两个距离之中最大的,也就是 2 。

    示例 2:

    输入:n = 8
    输出:0
    解释:8 的二进制是 “1000” 。
    在 8 的二进制表示中没有相邻的两个 1,所以返回 0 。

    示例 3:

    输入:n = 5
    输出:2
    解释:5 的二进制是 “101” 。

    class Solution:
        def binaryGap(self, n: int) -> int:
            #解法1:
            last, ans, i = -1, 0, 0
            while n:
                if n & 1:
                    if last != -1:
                        ans = max(ans, i - last)
                    last = i
                n >>= 1
                i += 1
            return ans
            #解法2:
            # idx = [i for i, v in enumerate(bin(n)) if v == '1']
            # return max([j - i for i, j in zip(idx, idx[1:])] + [0])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    java 搜索指定文件夹下指定字符串并将其写入 txt 文件中
    Node.js C++ 层的任务管理
    浅析基于AI智能识别技术的明厨亮灶智能化监管方案
    `maven.test.skip` 和 `skipTests` 的区别
    MACBOOK M1芯片上安装mongdb遇到的问题,以及安装教程
    pinctrl
    部署Kafka
    SpringBoot加载配置文件的顺序
    博安生物再次冲刺港交所上市:负债规模高企,持续出现亏损
    2022年web前端开发值得学习的10个javascript框架
  • 原文地址:https://blog.csdn.net/zag666/article/details/124379673