所以如果给我一个像
这样的数组a = {1, 2, 3}
我们知道给定的子阵列(包括非连续的)是(这代表功率集)
{1} {2} {3} {1,2,3} {1,2} {1,3} {2,3}
我也知道这些子集可以通过从
中计算二进制来表示000 -> 111 (0 to 7), where each 1 bit means we 'use' this value from the array
e.g. 001 corresponds to the subset {3}
我知道这个方法可以某种方式用于生成所有子集,但我不确定如何在c ++中实现它
所以基本上我要问的是如何(如果可以的话)二进制计数用于生成电源组?
任何其他生成电源组的方法也非常感谢!
答案 0 :(得分:5)
对于具有3个设置元素的示例,您可以这样做:
for (s = 1; s <= 7; ++s)
{
// ...
}
这是一个演示程序:
#include <iostream>
int main()
{
const int num_elems = 3; // number of set elements
const int elems[num_elems] = { 1, 2, 3 }; // mapping of set element positions to values
for (int s = 1; s < (1 << num_elems); ++s) // iterate through all non-null sets
{
// print the set
std::cout << "{";
for (int e = 0; e < num_elems; ++e) // for each set element
{
if (s & (1 << e)) // test for membership of set
{
std::cout << " " << elems[e];
}
}
std::cout << " }" << std::endl;
}
return 0;
}
编译和测试:
$ g++ -Wall sets.cpp && ./a.out
{ 1 }
{ 2 }
{ 1 2 }
{ 3 }
{ 1 3 }
{ 2 3 }
{ 1 2 3 }
注意,使最低有效位对应于第一个设置元素是一种常见的约定。
另请注意,我们省略了空集,s = 0,因为您似乎不想包含此内容。
如果你需要处理大于64个元素的集合(即uint64_t
),那么你需要一个更好的方法 - 你可以扩展上面的方法来使用多个整数元素,或者使用{{ 1}}或std::bitset
,或使用@Yochai的答案(使用std::vector<bool>
)。
答案 1 :(得分:0)
实际上创建集合非常简单 - 只需使用按位运算>>=
和&
一次测试一下。假设输入向量/数组a[]
已知有3个元素,因此产生7向量输出:
std::vector<std::vector<T>> v(7);
for (int n = 1; n <= 7; ++n) // each output set...
for (int i = 0, j = n; j; j >>= 1, ++i) // i moves through a[i],
// j helps extract bits in n
if (j & 1)
v[n-1].push_back(a[i]);
答案 2 :(得分:0)
对于编译时间大小,您可以使用bitset
,例如:
template <std::size_t N>
bool increase(std::bitset<N>& bs)
{
for (std::size_t i = 0; i != bs.size(); ++i) {
if (bs.flip(i).test(i) == true) {
return true;
}
}
return false; // overflow
}
template <typename T, std::size_t N>
void display(const std::array<T, N>& a, const std::bitset<N>& bs)
{
std::cout << '{';
const char* sep = "";
for (std::size_t i = 0; i != bs.size(); ++i) {
if (bs.test(i)) {
std::cout << sep << a[i];
sep = ", ";
}
}
std::cout << '}' << std::endl;
}
template <typename T, std::size_t N>
void display_all_subsets(const std::array<T, N>& a)
{
std::bitset<N> bs;
do {
display(a, bs);
} while (increase(bs));
}