Python算法——求集合的所有子集

二进制法:

①使用两层循环,外层循环为子集个数,对于集合长度为N,子集个数为 2的N次幂,外层循环每循环一次一个子集。内层循环用来判断二进制下标为j的位置数是否为1,如果是1,则输出,如果是0,则不输出。

②以集合[1,2,3]为例,N = len([1,2,3]),外层循环 i 取值范围为[0,7],内层循环⽤于判断i对应⼆进制下标为j的位置是否为1。如果(i>>j)%2为真,那么输出此⼦集。

③当 i =0时,无论 i 对应二进制000右移0位,1位,还是2位,即(i>>j)%2始终为0(假),输出空集。

④当i=1时, i对应二进制001右移0位,即(i>>j)%2为1(真),输出[1]。i对应二进制001右移1位为000,即(>>j)%2为0(假),不追加。i对应二进制001右移2位为000,即(i>>j)%2为0(假),不追加。最终输出[1]。

..............

⑤当i = 3时,i对应二进制011右移0位,即(i>>j)%2为1(真),输出[1]。i对应二进制011右移1位为001
即(i>>j)%2为1(真),追加输出[1,2]。i对应二进制011右移2位为000,即(i>>j)%2为0(假),不追加。最终输出[1,2]。
.............

⑥当i= 6时,i对应二进制110右移0位,即(i>>j)%2为0(假),输出[]。i对应二进制110右移1位为011
即(i>>j)%2为1(真),追加输出[2]。i对应二进制110右移2位为001,即(i>>j)%2为1(真),追加输出[2,3]。最终输出[2,3]。                                                                                                                              
⑦当i=7时,i对应二进制111右移0位,即(>>j)%2为1(真),输出[1]。i对应二进制111右移1位为011,即(i>>j)%2为1(真),追加输出[1,2]。i对应二进制111右移2位为001,即(i>>j)%2为1(真),追加输出[1,2,3]。最终输出[1,2,3]。
 

代码:

def PowerSetsBinary(items):
  N = len(items)
  for i in range(2**N):#[0-8)
    zj = []
    for j in range(N):#[0-3)
      if(i >> j ) % 2 == 1:
        zj.append(items[j])
    print(zj)
a='123'
PowerSetsBinary(a)

Python算法——求集合的所有子集_第1张图片

或者

def PowerSetsBinary(items):
  N = len(items)
  b=[]
  for i in range(2**N):
    zj =''
    for j in range(N):
      if(i >> j ) % 2 == 1:
        zj=zj+zj.join(items[j])
    b.append(zj)
  print(b)
a='ABCDE'
PowerSetsBinary(a)

你可能感兴趣的:(python)