📜  门| GATE CS 2019 |简体中文问题7(1)

📅  最后修改于: 2023-12-03 14:58:20.615000             🧑  作者: Mango

门 | GATE CS 2019 | 简体中文问题7

本题涉及比特操作和位运算。

题目描述

给定 $n$ 个 32 位整数,将每个整数的第 $j$ 个比特位提取出来形成一个新的整数。

例如,如果输入为 $n = 3$ 和 $a = {5, 1, 3}$,则输出应为 $b = {2, 0, 2}$,因为 $(5)_{10} = (101)2$,$(1){10} = (001)2$,$(3){10} = (011)_2$,因此我们提取第 $2$ 位得到 $2$,提取第 $0$ 位得到 $0$,提取第 $1$ 位得到 $2$。

解题思路

对于一个 32 位整数 $num$,第 $j$ 个比特位可以通过右移 $j$ 位后与 $1$ 进行按位与运算取出。即,第 $j$ 个比特位为 $num$ 的二进制表示中的最低位,右移 $j$ 位后最低位变为第 $j$ 个比特位,按位与运算后,只有第 $j$ 个比特位的值为 $1$,其余比特位都为 $0$,因此可以将第 $j$ 个比特位的值取出。

对于 $n$ 个整数,分别使用上述方法取出第 $j$ 个比特位,使用按位或运算将它们组合成一个新的整数即可。

下面给出 Python 解法的程序代码:

def extract_bits(n: int, a: List[int], j: int) -> int:
    b = 0
    for i in range(n):
        b |= (a[i] >> j) & 1  # 取出第 j 位,并按位或运算
    return b

在这里,我们使用了 Python 的位运算符 >>(右移)和 &(按位与),以及 |=(按位或赋值)操作符。其中,按位或运算符的运算过程如下:

按位或运算示例:

对于 $a = {5, 1, 3}$,$j = 1$:

$$\begin{aligned} b &= 0 \ & \quad \mid (5)_2 \gg 1 = (010)_2 \operatorname{~&~} 1 = (000)_2 \ & \quad \mid (1)_2 \gg 1 = (000)_2 \operatorname{~&~} 1 = (000)_2 \ & \quad \mid (3)_2 \gg 1 = (001)_2 \operatorname{~&~} 1 = (001)_2 \ & = (001)_2 \ \end{aligned}$$

因此,输出为 $2$。

完整程序
from typing import List

def extract_bits(n: int, a: List[int], j: int) -> int:
    b = 0
    for i in range(n):
        b |= (a[i] >> j) & 1
    return b

if __name__ == '__main__':
    n = int(input().strip())
    a = list(map(int, input().strip().split()))
    for j in range(32):
        print(extract_bits(n, a, j), end=' ')