在生成子序列时使用按位运算的逻辑是什么?
What is the logic to use bitwise operation in generating subsequences?
我有一个数组,A=[1,2,3,4](其中n=4)。我想从这个数组生成子序列。 子序列数为 (2^n -1)
从计数器 0001 运行到 1111
for (int counter = 1; counter < 2^n; counter++)
{
for (int j = 0; j < n; j++)
{
检查计数器中的第 j 位是否已设置。如果设置,则从 arr[] 打印第 j 个元素
if (counter & (1<<j))
cout << arr[j] << " ";
}
cout << endl;
}
}
谁能解释我?它是如何工作的" 计数器 & (1<</div>
逻辑是这样的。比如说,就像你在例子中放的那样,你有n = 4
,为了避免混淆,假设数组是A = [5, 7, 8, 9]
,例如。然后,您希望所有可能的序列都包含原始数组中的一些元素(至少一个)。所以你想要一个只包含第一个的序列,一个包含第一个和第二个的序列,第一个和第三个,等等。每个打印序列可能包含也可能不包含数组中的每个元素。所以你可以把它看作是这样的:
| 5 | 7 | 8 | 9 | Sequence
----------------- --------
| 1 | 0 | 0 | 0 | -> 5
| 1 | 1 | 0 | 0 | -> 5 7
| 1 | 0 | 1 | 0 | -> 5 8
...
也就是说,每个序列可以表示为一个位列表,每个位指示是否包含数组的每个成员。
在此循环中:
for (int counter = 1; counter < 2^n; counter++)
程序从1
迭代到2^n - 1
,在这种情况下15
。因此,您获得的counter
值为:
Dec Binary
--- ------
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
如果你仔细观察,你会发现我们有二进制的四个元素的所有可能的序列,由0
和1
组成(除了0000
,这将是空序列,我们不感兴趣)。在此循环中:
for (int j = 0; j < n; j++)
程序只是遍历counter
的每一点,从0
(最右边)到n - 1
,每当它找到一个1
它就会输出相应的数组元素。条件:
if (counter & (1<<j))
简单地计算1<<j
1
加上j
右边的零数(因此,例如,对于j = 0
,它将是1
,对于j = 2
,它将是100
),然后是按位和操作,因此它基本上仅"过滤"j
位(例如1101 & 100 = 0100
),如果结果不为零,则表示有一个,因此必须打印arr[j]
。
显然,该函数的问题在于它仅限于变量counter
可以容纳的位数。这取决于其声明的类型和体系结构/编译器,但通常它将是 32 或 64。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 在生成子序列时使用按位运算的逻辑是什么?
- 将临时值存储为某种数据类型时,算术运算的标准规则是什么
- 这是什么布尔运算?“表达式 * 布尔值”
- boost::multiprecision:乘以或除以 10 的巨大幂最便宜的方法是什么?类似于 10 次方的位移运算?
- 我怎么知道是什么使不完整类型不完整的错误:对指向不完整类型的指针进行算术运算