zoukankan      html  css  js  c++  java
  • 【算法】—— 集合的子集

    问题

    给定一个集合,输出它的所有子集。

    示例:

    给定集合{1,2,3},应该输出:

    {}

    {1}

    {2}

    {1, 2}

    {3}

    {1, 3}

    {2, 3}

    {1, 2, 3}

    解法1:增量构造法

    增量构造法,每次选择一个元素放到集合中,每次操作的结果即是一个子集。

    递归操作,每次向当前集合中添加一个比当前集合中最大的元素大1的数。

    from __future__ import print_function
     
    def print_subset(n, lst, cur):
        for i in range(cur):
            print(lst[i]+1, end='')
        print()
        if cur:
            s = lst[cur - 1] + 1
        else:
            s = 0
        for i in range(s, n):
            lst[cur] = i
            print_subset1(n, lst, cur+1)

    解法2:位向量法

    构造位向量(可理解为构造一个数组),该向量中的每一位置可以取0值或者1值,0和1分别代表该位置上对应的值是否在集合中。如向量为[1, 0, 0, 1],其第1和4位上有1,所以该向量表示的集合为{1, 4}。

    思路:
    如果需要用向量来表示集合,那么需要保证向量的每一种变化能够刚好覆盖集合的每一种可能性。

    对n求子集,构造长度为n的向量,每一位可以代表取或者不取该位置的值,共有2^n中可能。

    from __future__ import print_function
     
    def print_subset(n, lst, cur):
        if cur == n:
            for i in range(n):
                if lst[i]:
                    print(i+1, end='')
            print()
        else:
            lst[cur] = 0
            print_subset(n, lst, cur+1)
            lst[cur] = 1
            print_subset(n, lst, cur+1)

    解法3:二进制法

    我们可以使用二进制法来表示子集。对于n求子集,其子集有2^n个(包括空集),比如n = 4,其有16个子集,这16个子集用二进制可以表示成:

    0->0000->{}
    1->0001->{1}
    2->0010->{2}
    3->0011->{1,2}
    4->0100->{3}
    5->0101->{1,3}
    ...
    15->1111->{1,2,3,4}

    思路:

    求n的子集,可以依次处理1到2^n - 1之间的每一个数,每个数取出它二进制表示中的1的位置,以此表示该数对应的集合。比如5,二进制表示的后四位为0101,其在第1和第3位处有1,那么,其代表的集合为{1, 3}。使用位运算中与(&)操作,可以方便的求出二进制某位置上是否为1。

    from __future__ import print_function
    s = 1
    n = 4
    while s < (1 << n):  # 依次遍历1到2^n - 1之间的每一个数
        for i in range(n):  # 每一个数使用&操作判断该位置上是否有1,有打印或者保存起来
            if s & (1 << i):
                print(i+1, end='')
        print()
        s += 1
  • 相关阅读:
    c++ fstream中seekg()和seekp()的用法
    java连接MySql数据库
    AspNetPager查询分页问题(点击页码,不再是查询后的数据集)viewstate解决
    C#操作XML文档
    关于PHP程序员解决问题的能力
    HDOJ 1874( dijkstra )
    错排问题 (Mathematics)
    中缀表达式到后缀表达式 (Data_Structure)
    几次到1(分治递归)
    max(int) = 0x7fffffff
  • 原文地址:https://www.cnblogs.com/bopo/p/9255623.html
Copyright © 2011-2022 走看看