位运算|豆包MarsCode AI刷题

77 阅读4分钟

一、位运算

在现代计算机中,所有数据都以二进制形式存储,即 0 和 1 两种状态。计算机对二进制数据进行的运算(如加、减、乘、除)被称为位运算,即对二进制数的每一位进行操作的运算。

所以,与直接使用 +、-、*、/ 运算符相比,合理运用位运算可以显著提高代码在机器上的执行效率。

二、位运算概览

符号描述运算规则
&两个位都为1时,结果才为1
两个位都为0时,结果才为0
异或两个位相同为0,相异为1
~取反0变1,1变0
<<左移各二进位全部左移若干位,高位丢弃,低位补0
>>右移各二进位全部右移若干位,高位补0或符号位补齐

一、位与

0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1

总结:只有两位同时为1时,结果才为1,否则结果为0。

例如:3 & 5 即 0000 0011 & 0000 0101 = 0000 0001,因此 3 & 5 的值为1。

二、位或

0 | 0 = 0 0 | 1 = 1 1 | 0 = 1 1 | 1 = 1

总结:只要有一个为1,其值为1。

例如:3 | 5 即 0000 0011 | 0000 0101 = 0000 0111,因此 3 | 5 的值为7。

注意:负数按补码形式参与按位或运算。

三、异或

0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0

总结:相应位相同为0,相异为1。

四、取反

~1 = 1111 1110 ~0 = 1111 1111

总结:将 0 变 1,1 变 0。

五、左移

定义:将一个运算对象的各二进制位全部左移若干位,高位丢弃,低位补0。

例如,设 a = 1010 1110a = a << 2 将 a 的二进制位左移2位、右补0,即得 a = 1011 1000

若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。

六、右移

定义:将一个数的各二进制位全部右移若干位,高位补0或补符号位,右边丢弃。

例如,a = a >> 2 将 a 的二进制位右移2位,左补0 或补符号位,具体取决于数的正负。

操作数每右移一位,相当于该数除以2。

题目:二进制转码问题

问题描述

小C在学习二进制运算,他了解到每个非负整数都有其二进制表示。例如,整数 5 可以被表示为二进制 "101",整数 11 可以被表示为二进制 "1011",并且除了 N = 0 外,任何二进制表示中都不含前导零。

二进制的反码表示是将每个 1 变为 0,每个 0 变为 1。例如,二进制数 "101" 的二进制反码为 "010"。现在小C想知道,给定一个十进制数 N,它的二进制反码对应的十进制数是多少。


测试样例

样例1:

输入:N = 5
输出:2

样例2:

输入:N = 10
输出:5

样例3:

输入:N = 0
输出:1

思路

  1. 十进制转二进制

    • 使用栈来存储每次除以2的余数,这样可以从低位到高位构建二进制数。
    • 代码中使用了 while N > 0 循环,每次取 N 除以2的余数,并将余数压入栈 s 中,然后将 N 更新为 N // 2(整除)。
  2. 构建二进制字符串

    • 接着使用 while len(s) > 0 循环,将栈中的元素依次弹出并拼接成字符串 binstring,这样就得到了 N 的二进制表示。
  3. 补码操作

    • 代码中的补码操作实际上是将二进制数中的 1 替换为 20 替换为 1,然后再将所有的 2 替换为 0。这个过程实际上并没有改变二进制数的值,只是进行了一次无意义的字符替换。
  4. 将补码字符串转换为十进制

    • 最后,将得到的补码字符串 binstring_comple_3 转换为十进制数 binstring_comple_ten 并返回。

代码

def solution(N):
    #十进制转二进制
    #1.栈实现;2.bin()
    #binnum = bin(N)
    #return binnum
    #bin带二进制0b前缀,可用[2:]舍去前缀
    #定义栈
        if N == 0:
                return 1
        
        s = []
        binstring = ''
        while N > 0:
                #余数进栈
                rem = N % 2
                s.append(rem)
                N = N // 2
        while len(s) > 0:
               #元素全部出栈即为所求二进制数
               #栈(后进先出),pop()从栈s中移除并返回最后一个元素
               binstring = binstring + str(s.pop())
        #互换需要中间元素
        binstring_comple_1 = binstring.replace('1','2')
        binstring_comple_2 = binstring_comple_1.replace('0','1')
        binstring_comple_3 = binstring_comple_2.replace('2','0')
        binstring_comple_ten = int(binstring_comple_3, 2)
        return binstring_comple_ten