zoukankan      html  css  js  c++  java
  • 求子集算法

    题目:

    试编写一个函数,用来输出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} 
  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/JoannaQ/p/2972975.html
Copyright © 2011-2022 走看看