按位 & 和 << 如何帮助解决这个子集问题?

How does bitwise & and << help in this subset problem?

我正在学习如何在 Javascript 中打印所有长度相同的子集。我在 w3resource.com 上看到 this solution:

JavaScript Function: Exercise-21 with Solution


Write a JavaScript function to get all possible subset with a fixed length (for example 2) combinations in an array.

Sample array : [1, 2, 3] and subset length is 2

Expected output : [[2, 1], [3, 1], [3, 2], [3, 2, 1]]

JavaScript Code:

function subset(arra, arra_size) {
    var result_set = [], 
        result;
    for(var x = 0; x < Math.pow(2, arra.length); x++) {
        result = [];
        i = arra.length - 1; 
        do {
            if( (x & (1 << i)) !== 0) {
                result.push(arra[i]);
            }
        }  while(i--);
        if( result.length >= arra_size) {
            result_set.push(result);
        }
    }

    return result_set; 
}

但是我不明白代码背后的逻辑,尤其是带有按位运算符的那一行。谁能解释一下?

(x & (1 << i)) !== 0 表示“x 是否将 ith 位设置为 1?”

一个例子:

假设 x 的二进制表示是 1001101

然后让 i 从 6 下降到 0(这就是 do 循环所做的)

然后我们得到:

i 1 << i (binary) x & (1 << i) (binary)
6 1000000 1000000
5 100000 0
4 10000 0
3 1000 1000
2 100 100
1 10 0
0 1 1

外循环将生成所有可能的二进制位模式,其位数与数组中的值一样多。

这样,那些位模式 (x) 实际上描述了数组的所有可能子集(1 位表示:包含相应的数组值,0 表示:不包含它)。位移运算符有助于隔离位模式中的一位,从而决定是否包含相应的数组值。

有关 Bitwise AND (&) and Left shift (<<)

的文档,请参阅 MDN