直接找到子集 c

finding subsets dicretely c

for (i = 0; i < (pow(2,n)-1); i++) {
    x = binary_conversion(i);
    for (j = (n-1); j > 0; j--) {

        if (x == 0) {
            M[i][j] = 0;
        }
        else {
            M[i][j] = x % 10;
            x = x / 10;
        }
    }
}

我想打印一个集合的子集,所以对于一组 n 个元素,我得到 2^n 的值。从 0 到 2^n,我正在将值转换为二进制。我将二进制值保存在一个矩阵中,当我遍历矩阵时,如果值为 1,我将在创建矩阵时打印原始 set.But 的相应元素,它将相同的二进制值分配给连续两行,所以最后我什至无法获得一半的子集。您认为代码有什么问题?

啊,因为你没有覆盖 LSB 或第 0 个元素。 for (j = (n-1); j >= 0; j--) 你错过了 =.

您还必须知道第 j 位是否设置在 i 中。

您可以简单地使用 (1<<n)[相当于 2^n]

而不是 pow

您的代码不可读。我将 post 伪代码。

for ( int i = 0; i<= (1<<numOfSetElmts)-1; i++)
{
     //print Subset-i
     for(int pos = 0; pos<=n-1;pos++)
       if( i&(1<<pos) )
         print Set[pos]
}

为什么我不使用 pow

pow函数是通过算法实现的,使用浮点函数和数值来计算幂值。

所以浮点数的n次方不一定是重复乘n次。结果,您最终会遇到一些错误,并且执行速度也会变慢。

按位更快?

是的。即使现代实现正在对整个体系结构进行更改,但您仍然不会因按位使用而失去性能。如果不相等,它们中的大多数将比加法运算具有更好的性能。

你的程序最复杂。这个问题有更好的解决方案,而且复杂性最低。无论如何,您的代码的问题是 '<='

i <= pow(2,n)-1

您也可以使用 i < 1<<n 两者的工作原理相同,但第二个更好更快。同样的问题发生在你没有放置'='符号的内部循环中。即 j>=0 。其他节目还不错。

您的问题的更好解决方案可能如下所示。

void subsets(char A[], int N)
{
    int i,j;
    for( i = 0;i < (1 << N); ++i)
    {
        for( j = 0;j < N;++j)
            if(i & (1 << j))
                printf("%c  ",  A[j] );
        printf("\n");
    }
}

这里不需要外部二进制转换或矩阵。