求子集算法

题目:

试编写一个函数,用来输出n 个元素的所有子集。例如,三个元素{a, b, c} 的所有子集是:{ }(空集),{a}, {b}, {c}, {a, b}, {a, c}, {b, c} 和{a, b, c}。

递归求子集

void combination(char *s, int p, int q, bool *flag)
{
    if (p == q)
    {
        for (int i=0; i<q; i++)
        {
            if(flag[i])
                putchar(s[i]);
        }
        puts("");
        return;
    }

    flag[p] = false;
    combination(s,p+1,q, flag);
    flag[p] = true;
    combination(s,p+1,q, flag);
}

int main()
{
    char *str = "abcd";
    bool flag[4] = {0};
    combination(str, 0, 4, flag);
    return 0;
}

每个元素有在与不在子集内两种选择,因此含n个元素的集合的子集数为 2^n。用一个标记数组表示该元素在与不在,然后再递归剩余元素。

非递归求子集

import java.util.BitSet;  
import java.util.HashSet;  
import java.util.Iterator;  
import java.util.Set;  
public class FindSubset {  
    private BitSet start;  
    private BitSet end;  
    private Set<Set<Object>> subsets;  
    public FindSubset() {  
        this.start = new BitSet();  
        this.end = new BitSet();  
        this.subsets = new HashSet<Set<Object>>();  
    }  
    public void execute(int n, Set<Object> items) {  
        int size = items.size();  
        for (int i = 0; i < n; i++) {  
            start.set(i, true);  
        }  
        for (int i = n; i < size; i++) {  
            start.set(i, false);  
        }  
        for (int i = size - 1; i > size - n; i--) {  
            end.set(i, true);  
        }  
        for (int i = 0; i < size - n; i++) {  
            end.set(i, false);  
        }  
        find(items);  
        while (start != end) {  
            boolean endBit = start.get(size - 1);  
            int last10 = -1;  
            int i;  
            for (i = size - 1; i > 0; i--) {  
                boolean former = start.get(i - 1);  
                boolean last = start.get(i);  
                if (former == true && last == false) {  
                    last10 = i - 1;  
                    break;  
                }  
            }  
            if (i == 0) {  
                break;  
            } else {  
                if (endBit == false) {  
                    start.set(last10, false);  
                    start.set(last10 + 1, true);  
                    find(items);  
                } else {  
                    start.set(last10, false);  
                    start.set(last10 + 1, true);  
                    last10 += 1;  
                    for (int j = last10 + 1; j < size; j++) {  
                        if (start.get(j)) {  
                            start.set(j, false);  
                            start.set(last10 + 1, true);  
                            last10 += 1;  
                            find(items);  
                        }  
                    }  
                }  
            }  
        }  
    }  
    public void find(Set<Object> items) {  
        Set<Object> temp = new HashSet<Object>();  
        Object elements[] = items.toArray();  
        for (int i = 0; i < elements.length; i++) {  
            if (start.get(i)) {  
                temp.add(elements[i]);  
            }  
        }  
        subsets.add(temp);  
    }  
    public Set<Set<Object>> getSubsets() {  
        return this.subsets;  
    }  
      
    public void clearSubsets(){  
        this.subsets.clear();  
    }  
    public static void main(String[] args) {  
        Set<Object> items = new HashSet<Object>();  
        items.add("A");  
        items.add("B");  
        items.add("C");  
        items.add("D");  
        items.add("E");  
        items.add("F");  
        FindSubset fs = new FindSubset();  
        for (int i = 0; i < items.size(); i++) {  
            System.out.println((i + 1) + "元子集:");  
            fs.execute(i + 1, items);  
            Iterator<Set<Object>> iterator = fs.getSubsets().iterator();  
            while (iterator.hasNext()) {  
                Object[] subset = iterator.next().toArray();  
                System.out.print("{");  
                for (int j = 0; j < subset.length - 1; j++) {  
                    System.out.print(subset[j] + ",");  
                }  
                System.out.print(subset[subset.length - 1]);  
                System.out.println("}");  
            }  
              
            fs.clearSubsets();  
        }  
    }  
} 

输出结果:

1元子集:  
{D}  
{E}  
{F}  
{A}  
{B}  
{C}  
2元子集:  
{D,E}  
{F,C}  
{E,C}  
{F,B}  
{E,F}  
{D,F}  
{A,B}  
{B,C}  
{D,A}  
{A,C}  
{D,C}  
{E,B}  
{F,A}  
{D,B}  
{E,A}  
3元子集:  
{E,F,B}  
{D,F,C}  
{E,F,A}  
{D,F,B}  
{D,E,C}  
{D,E,F}  
{E,F,C}  
{F,A,B}  
{E,A,C}  
{D,B,C}  
{E,A,B}  
{D,A,C}  
{F,B,C}  
{D,F,A}  
{D,E,B}  
{F,A,C}  
{E,B,C}  
{D,E,A}  
{D,A,B}  
{A,B,C}  
4元子集:  
{D,E,F,C}  
{D,E,F,B}  
{E,F,B,C}  
{D,E,F,A}  
{D,A,B,C}  
{E,A,B,C}  
{E,F,A,B}  
{D,F,A,C}  
{D,E,B,C}  
{E,F,A,C}  
{D,F,B,C}  
{F,A,B,C}  
{D,E,A,B}  
{D,F,A,B}  
{D,E,A,C}  
5元子集:  
{D,E,F,B,C}  
{D,E,F,A,C}  
{D,E,F,A,B}  
{E,F,A,B,C}  
{D,F,A,B,C}  
{D,E,A,B,C}  
6元子集:  
{D,E,F,A,B,C} 

 

 

转载于:https://www.cnblogs.com/JoannaQ/archive/2013/03/21/2972975.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值