用二进制操作求解集合所有子集

题目

有一个集合S,要求打印出其所有子集,子集元素用,隔开。比如集合S ={“A”,“B”},其子集分别为,“A,B” ,“A”, “B” ,NULL 四个。其中S本身和空集都可以认为是S的子集。

算法描述

以S ={“A”,“B”,“C”}为例,集合中包含三个元素,那么让S对应3个位长的二进制数,在子集中取1,不在子集中取0,即:

111(7)->A B C

110(6)->A B

101(5)->A C

100(4)->A

011(3)->B C

010(2)->B

001(1)->C

000(0)->NULL

代码实现

def fixBinaryString(val, setlen):
    '''
    必须保持val的二进制长度与集合长度一致,例如如果集合有3个元素,val=2,那么它的二进制形式是0b11
    函数在高位补足一个0,于是0b11转换为0b011,这样在打印集合元素时才能根据二进制位对应得上每一个元素
    '''
    binary = bin(val).replace('0b', '')
    while len(binary) < setlen:
        binary = "0" + binary
    return binary


def printSetByBinary(val, collection):
    '''
    根据整数二进制形式中比特位上的值是0还是1选择是否把对应元素打印到子集中
    '''
    # 先把整形对应的二进制位数根据集合元素个数补全
    binary = fixBinaryString(val, len(collection))
    idx = 0
    isNull = True
    while idx < len(binary):
        # 如果对应比特位是1,那么就打印对应的集合元素
        if binary[idx] == '1':
            if isNull is False:
                print(",", end='')
            print(collection[idx], end='')
            isNull = False
        idx += 1
    if isNull is True:
        print("NULL")
    print(";")


def handleAllSubSet(set):
    count = len(set)
    val = 0
    # 根据集合中元素的个数构造相应位长的二进制数,并把所有对应的比特位都设置为1
    for i in range(count):
        val |= (1 << i)
    while val >= 0:
        printSetByBinary(val, set)
        val -= 1

collection = ["A","B","C"]
handleAllSubSet(collection)

运行结果:

A,B,C;
A,B;
A,C;
A;
B,C;
B;
C;
NULL
;

算法分析

对于一个n位长的二进制数,所有可能取值的情况公有2^n种,因此算法的复杂度就是O(2 ^n)。这种指数级的时间复杂度效率是很低的,但就这种问题而言,我们更注重的应该是解题思路,算法效率并不是重点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰履踏青云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值