如何使用C ++有效地生成所有项目选择方式?
例如,如果有项目A,B和C.
[A,B,C] => [A], [B], [C], [A,B], [B,C], [A,C], [A, B, C]
答案 0 :(得分:2)
基本上,你可以将问题分解为:“对于每个项目,它是否是集合的一部分”。如果您能找到所有组合,那么您可以找到所有可能的选择项目的方法。
表示项目是否在集合中的方法是使用布尔值。如果它在集合中则为真或1,如果不在,则为0;如果不在,则为0。所以我们需要为每个项目设置一个布尔值。这会让人联想到int
或其他类型,因为它们本质上都是一堆。
现在我们怎样才能找到这些布尔值的所有组合。有一个简单的答案:遍历所有整数。例如:
ABCD Number in base 10
0000 0
0001 1
0010 2
0011 3
0100 4
.... ...
1111 (2^4) - 1
我们知道有2^4
个答案,因为每个项目可以在集合中,或者不在集合中,因此每个项目有2种可能性。如果有4个元素,则有2*2*2*2
或2^4
个组合。
还有一种简单的方法可以找到2^n
。只需做1 << n
。
这引出了一个简单的答案:
for (int i = 0; i < (1 << n); i++) {
// Here the ath bit of i will be set if the ath item is part of the set
}
请注意,这将包括空集,即[ ]
。如果你不想这样,只需从1而不是0开始循环。
希望这有帮助。
答案 1 :(得分:2)
对于该输入集:
#include <iostream>
void print(int b, char *a, int n)
{
for(int i = 0 ; i < n ; i++)
{
if( b & 0x1) std::cout << a[i];
b = b >> 1;
}
std::cout << std::endl;
}
int main() {
char a[] = {'A','B','C'};
for(int i = 1 ; i < 8 ; i++ )
print(i,a,3);
return 0;
}
输出:
A
B
AB
C
AC
BC
ABC
现在轮到改进和概括这种方法,并发现它的限制。
答案 2 :(得分:1)
如果您有N个元素(此处N = 3),则从i
迭代1
到(1<<3)
,并在每次迭代中查看i
的二进制值。< / p>