approach 1
def PowerSetsBinary(items):
N = len(items)
# generate all combination of N items
# enumerate the 2**N possible combinations
for i in range(2 ** N):
combo = []
for j in range(N): # jth bit of Integer i
if (i >> j) % 2 == 1:
combo.append(items[j])
yield combo
"""
[]
['a']
['b']
['a', 'b']
['c']
['a', 'c']
['b', 'c']
['a', 'b', 'c']
"""
Question 1
- 为什么是向右移动j位
- 答:对二进制数向右移动j位, 是在减小该数字
- 为什么是判断除以2 余1
- 答: Explore it yourself !
- 为啥通过j下标来去items的值
- 答:一方面, j的取值范围和数组的对应关系, 另一方面, 每次向右移动j次,判断结果除以2 余1 来得到是否要取当前的下标对应的值
很神奇
a_2(能不能把它修改成尾递归)
def PowerSetsRecursive(items):
"""Use recursive call to return all subsets of items, include empty set"""
if len(items) == 0:
# if the lsit is empty, return the empty list
return [[]]
subsets = []
first_elt = items[0] # first element
rest_list = items[1:]
# Strategy: Get all subsets of rest_list;
# for each of those subsets,a full subset list will contain both the original subset
# as well as a version of the subset that contains the first_elt(according to my a_2 思路,you will understand this)
for partial_subset in PowerSetsRecursive(rest_list):
subsets.append(partial_subset)
next_subset = partial_subset[:] + [first_elt]
subsets.append(next_subset)
return subsets # 递归退层后都要 返回递归进层的subsets
a_2思考
适合用尾递归吗?(NOT ACKNOWLEDGE)
答:尾递归意味着每一层需要存储该层的数据,以便省去递归退层的步骤,当求子集的基例是当长度为0时候,返回[[]]
a_2 思路
a_3
def PowerSetsRecursive2(items):
# items need to depend on the former ones , then form into new results
# the power set of the set <集合的幂集> has one element at least
result = [[]]
for x in items:
# 两个列表相加和extend同理
result.extend( [subset + [x] for subset in result] )
return result
测试
extend是把列表(参数)解包后加入列表
append直接把列表(参数)加入列表
result.extend( [subset + [x] for subset in result] ) 修改成
result.append( subset + [x] for subset in result )-----> 除第一个元素外,其他均是变成生成器对象