转载:三种实现集合求子集合算法

来源:互联网 发布:java runonthread 编辑:程序博客网 时间:2024/06/12 01:37

以下内容转载自:ITeye narutolby 的日志
略有调整,不影响主体内容,仅供参考学习。

题目:给定一个集合,求该集合的所有子集合,如集合{1,2}的子集合有{}(空集是所有集合的子集),{1},{2},{1,2},共2^2个子集合,下面给出两种解法,其中第一种解法分递归与非递归实现,都用java实现
【第一种解法】
算法思想:给定一个集合,求子集合过程可分为以下两个步骤:
(1)把集合分为两部分,第一个元素和剩余元素,如{1,2,3}分为1和{2,3}
(2)原集合的所有子集合为剩余元素的子集合并上把第一个元素加入所有子集合,如{2,3}的子集合为{2},{3},{2,3},{},那么把第一个元素1加入这些子集合,则构成{1,2},{1,3},{1,2,3},{1},把这些集合合并起来,则原集合的所有子集合便为{2},{3},{2,3},{},{1,2},{1,3},{1,2,3},{1},代码如下:

// 非递归方式    static ArrayList<ArrayList<String>> getSub(String args[])    {        ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();        ArrayList<ArrayList<String>> temp = null;        ArrayList<String> element = null;        //添加为空的子集        result.add(new ArrayList<String>());        for (int i = 0; i < args.length; i++)        {            temp = new ArrayList<ArrayList<String>>();            for (int j = 0; j < result.size(); j++)            {                element = new ArrayList<String>();                element.add(args[i]);                element.addAll(result.get(j));                temp.add(element);            }            result.addAll(temp);        }        return result;    }
// 采用递归算法    static ArrayList<ArrayList<String>> getSub2(String args[], int index)    {        ArrayList<ArrayList<String>> result = null;        ArrayList<ArrayList<String>> temp = null;        ArrayList<String> element = null;        String item = null;        if (args.length == index)        {            result = new ArrayList<ArrayList<String>>();            result.add(new ArrayList<String>());        }        else        {            result = getSub2(args, index + 1);            item = args[index];            temp = new ArrayList<ArrayList<String>>();            for (ArrayList<String> sub2 : result)            {                element = new ArrayList<String>();                element.addAll(sub2);                element.add(item);                temp.add(element);            }            result.addAll(temp);        }        return result;    }

【第二种解法】
算法思想:n个元素的集合,在构造子集合过程中,每个元素有两种情况,在子集合中“存在”与“不存在”,“存在”用“1”表示,“不存在”用“0”表示,这样共有2^n种情况,即2^n个子集合。此时我们想到用长度为n的二进制数字 “1111….000…”,1表示该位置在子集合中存在,0表示该位置在子集合中不存在,让该二进制数从0 一直加到 2^n,则所有情况都会出现,代码如下

// 通过二进制的方法    static ArrayList<ArrayList<String>> getSub3(String args[])    {        ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();        ArrayList<String> subList = null;        int max = 1 << args.length;        for (int i = 0; i < max; i++)        {            subList = new ArrayList<String>();            int k = i;            int index = 0;            while (k > 0)            {                if ((k & 1) > 0)                {                    subList.add(args[index]);                }                k >>= 1;                index++;            }            result.add(subList);        }        return result;    }

测试方法

public static void main(String[] args)    {        String array[] =        {                "a", "b", "c", "d"        };        ArrayList<ArrayList<String>> list = null;        //list = getSub(array);        // list = getSub2(array, 0);         list = getSub3(array);        for (int i = 0; i < list.size(); i++)        {            ArrayList<String> subList = list.get(i);            System.out.println(subList.toString());        }    }
原创粉丝点击