求一个集合的所有子集

1,684 阅读2分钟

有两种方式 

方法一: 位(二进制) 

主要思路: 

就是元素选与不选,用二进制来代表选与不选的情况. "1"代表这个元素已经选择 而 "0" 代表这个元素没有选择. 假如 三个元素是abc 那么101 就代表b没有选择 所以 101 代表的子集位ac 

 以下是代码

func getSubsets<T>(set :Set<T>) -> Array<Set<T>>{
    let count = 1 << set.count  //平方根
    let elements = Array(set)
    var subsets = [Set<T>]()
    for i in 0..<count {
        var subset = Set<T>()
        for j in 0..<elements.count {
            //右移一位
            if ((i >> j) & 1) == 1{
                subset.insert(elements[j])
            }
        }
        subsets.append(subset)
    }
    return subsets
}


 方法二:递归  

主要思路: 

如果只有一个元素,那么他的子集有两个,分别是本身和空集,然后在已经有一个元素的子集的基础上,第二个元素有两种选法,那就是加入到前面的子集里面或者不加入到前面的子集里面,也就是选与不选的问题.而前面的子集一共有两个,对每一个子集都有来自于下一个元素的加入和不加入两种选法.那么就可以得出一个结论:两个元素的子集一共有四个.依次类推,就可以得出n个元素的所有子集.注意:n个元素的子集总共有2n个,非空子集一共有2n-1个 

 主要代码:

func getSubsets1<T>(_ set:Set<T>) -> Array<Set<T>> {
    let elements = Array(set)
    return getSubsets3(elements,index: elements.count - 1,count: elements.count)
}


func getSubsets2<T>(_ elements:Array<T>,index:Int,count:Int) -> Array<Set<T>>{
    var subsets = Array<Set<T>>()
    if index == 0 {
        subsets.append(Set<T>())
        var subset = Set<T>()
        subset.insert(elements[0])
        subsets.append(subset)
        return subsets
    }
    subsets = getSubsets3(elements, index: index - 1, count: count)
    for subset in subsets {
        var subsetWithCurrent = Set(subset)
        subsetWithCurrent.insert(elements[index])
        subsets.append(subsetWithCurrent)
    }
    return subsets
}

相互学习,欢迎大神指正....