3种方法求子集_python_递归 ???

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 )-----> 除第一个元素外,其他均是变成生成器对象

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值