【数字题2】求一个数组的全部子集

【问题描述】

{},

{a}, {b}, {c}, {d},

{a, b}, {a, c}, {a, d}, {b, c}, {b, d}, {c, d},

{a, b, c}, {a, b, d}, {a, c, d}, {b, c, d},

{a, b, c, d}

一共16个,事实上n个元素的集合的子集共有2n个(包含空集)。

【方法一】递归

定义一个元素数组mark[ ],用来存放第i个元素,当第i个元素不出现在子集中,对应的位置为空。伪代码如下:

共n个元素,每个元素取或不取,       
subset(判断第i个元素)     
{           
   若i是最后一个元素(i>=n):
       连续输出mark数组中的所有值,空的不打印,返回。           
   否则:            
       不取第i个元素,           
       subset(判断第i+1个数)             
       取第i个元素,          
       subset(判断第i+1个数)     
}   

【方法二】位操作

集合set={a,b,c,d},对于任意一个元素,在每个子集中,要么存在,要么不存在,对应关系是:

a->1或a->0

b->1或b->0

c->1或c->0

映射为子集:

(a,b,c)

(1,1,1)->(a,b,c)

(1,1,0)->(a,b   )

(1,0,1)->(a,   c)

(1,0,0)->(a      )

(0,1,1)->(   b,c)

(0,1,0)->(   b   )

(0,0,1)->(      c)

(0,0,0)->@ (@表示空集)

void findSubset(char *array,int len) {
    int mask,index;
    int subset_len = 1 << len;//2^len
    for (int i = 0; i < subset_len; i++) {
        mask = i;
        index = 0;
        while (mask){
            if (mask & 1)
                cout << array[index];
            mask >>= 1;
            ++ index;
        }   
        cout <<endl;
    }   
}

当然还要输出空集,上面的代码省略了这一行。

点赞