“n”对象上的子集集

时间:2013-07-28 03:08:10

标签: c++ c++11 set subset

假设我有2个元素{a,b}。现在给出一个数字“n”,我希望以“n”元素的所有子集集合添加所有这些子集包括所有“n”元素。在这里,我们可以拥有({a} and {b})({a,b})的子集。在一组三个元素{a,b,c}中,我拥有所有子集集({a},{b},{c})({a,b},{c})以及({a},{b,c})({a,c},{b})以及({a,b,c})。如何在C++中编写程序作为函数来取数字“n”并给出这些子集的所有集合。

2 个答案:

答案 0 :(得分:1)

我不确定我是否理解你的问题,但我认为你正在考虑分区 递归地想一想这个问题 要对一组n个元素进行分区,请运行一个迭代其所有子集的循环 现在,只需将子集的补码(通过递归找到)的分区附加到当前正在迭代的子集中。

答案 1 :(得分:0)

你可以这样做,使用公式来找到一次采取的n个事物的组合。

nCr = n! / r! (n-r)!
例如,找到一组3的所有组合,一次取两件事(a,b,c)(a,b),...

C = 3! / 2! (3-2)!
C = 6 / 2(1)
C = 3 distinct combinations are possible for set (a,b,c) in a subset of 2:
(a,b), (a,c), (b,c)

finding all of them
nCr(where n and r = 3) = 1 set (a,b,c)
nCr(n=3, r=1) = 3 = 3 sets (a),(b),(c)
include empty set {}
C = 8

要查找所有可能的集合,您可以使用for循环将r递减到0.从我记忆中的组合/置换开始,空集{}也会被计算。

这是在c ++函数中的样子(这是相当基本的)

unsigned int factorial(unsigned int i)
{
    unsigned int sum = 0;

    if (i > 1)
    {
        sum = i;
        --i;
        for (i; i > 1; --i)
            sum *= i;
    }// 1! and 0! are 1
    else 
        return 1;


    return sum;
}

unsigned int allsubsets(unsigned int n)
{
    unsigned int C = 0;
    for (int r = n; r > 0; --r)
    {
        C += ( factorial(n) / ( factorial(r) * factorial(n-r) ) );
    }
    ++C; // include the null set
    return C;   
}

int main()
{
    std::cout << "C of 1 is: " << allsubsets(1) << std::endl;
    std::cout << "C of 2 is: " << allsubsets(2) << std::endl;
    std::cout << "C of 3 is: " << allsubsets(3) << std::endl;
    std::cout << "C of 4 is: " << allsubsets(4) << std::endl;
    std::cout << "C of 5 is: " << allsubsets(5) << std::endl;

    return 0;
}

打印:

C of 1 is: 2
C of 2 is: 4
C of 3 is: 8
C of 4 is: 16
C of 5 is: 32