给定随意长度的一个集合。用一个数组表示,如{"a", "b","c"},求它的全部子集。结果是{ {a}, {b}, {c}, {a,b}, {a,c}, {b,c}, {a,b,c}}和一个空集。

以下讲的就是怎样用一个原始的傻瓜方法(非算法)求它的全部子集。

首先我们知道是它的子集个数是2^length,假设长度是3,那子集就共同拥有2的3次方=8个,包含空集。

求子集,我的做法是对不论什么一项做推断,有或者无,用1和0来相应表示。

那么像这样的长度为3的,用二进制来表示就是000、001、010……

事实上就是从0-2^3,用2进制表示出来就是所以的子集了。然后把0相应的子项给拿掉。譬如010相应的就是b,011相应的就是bc。

仅仅须要从0到2^3-1做一个循环。然后把0-7之间的数用二进制表示出来,再与原集合进行对照。

把0相应位置的字符去掉,这样就得到了全部子集。

原理非常easy,以下是代码

package huisu;

/**
* Created by wolf on 2016/3/22.
*/
public class GetSet {
private String[] origin = {"a", "b", "c"}; private String[] targetArray; public static void main(String[] args) {
new GetSet().doJob();
} private void doJob() {
//获取将要分解的字符串假设转为2进制最大是几
//如字符串是3位。就是2^3。 从[0 0 0]到[1 1 1]
int maxLength = (int) Math.pow(2, origin.length);
targetArray = new String[maxLength]; for (int i = 0; i < targetArray.length; i++) {
//十进制转2进制
targetArray[i] = Integer.toBinaryString(i);
} buling(); print();
} /**
* 给空位补0,凑齐位数
*/
private void buling() {
for (int i = 0; i < targetArray.length; i++) {
//位数是完整的,不须要补0
if (targetArray[i].length() == origin.length) {
continue;
}
String temp = "";
//0,1,10,11,111
for (int j = 0; j < origin.length - targetArray[i].length(); j++) {
temp += "0";
}
targetArray[i] = temp + targetArray[i];
}
} private void print(){
for (int i = 0; i < targetArray.length; i++) {
String s = targetArray[i];//如000,001,010
for (int j = 0; j < s.length(); j++) {
char item = s.charAt(j);
if (item == '1') {
System.out.print(origin[j]);
}
}
System.out.println();
}
}
}

在第23行是将10进制的0-7转成二进制,转之后例如以下图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

这里就有个问题,那就是位数并不满。像0、10之类的,将来和原始数组做相应推断的时候有点小麻烦,所以我做了个处理,把位数补齐。保持和原始数组位数一样。

调用了buling(原谅我想不起来用什么英语来表示补零)方法。把位数不足的前面全补上0.然后就变成了000,001,010……这样就能够非常方便的去推断了,仅仅打印1所在的位数即可了。參考print方法。

总结:这样的做法比較简单易懂。也能适应随意长度的求子集问题。

依据这样的做法,还能解决另外一个问题——01背包问题(有编号分别为a,b,c,d,e的五件物品。它们的重量各自是2,2,6,5,4,它们的价值各自是6,3,5,4,6。如今给你个承重为10的背包。怎样让背包里装入的物品具有最大的价值总和?)相信非常easy能看出来,上面的方法求出来了全部子集,那么对于01背包问题。就是依据全部的子集。先砍掉全部超重的子集。然后去计算剩余的子集的价值,找到最大的就OK了。

傻瓜方法求集合的全部子集问题(java版)的更多相关文章

  1. DFS算法-求集合的所有子集

    目录 1. 题目来源 2. 普通方法 1. 思路 2. 代码 3. 运行结果 3. DFS算法 1. 概念 2. 解题思路 3. 代码 4. 运行结果 4. 对比 1. 题目来源 牛客网,集合的所有子 ...

  2. Java 求集合的所有子集

    递归方法调用,求解集合的所有子集. package ch01; import java.util.HashSet; import java.util.Iterator; import java.uti ...

  3. 图方法:寻找无向图联通子集的JAVA版本

    图像处理中一般使用稠密方法,即对图像进行像素集合进行处理.在图像拓扑方面,更多地应用图计算方法. 寻找无向图联通子集的JAVA版本,代码: //查找无向图的所有连通子集//wishchin!!! pu ...

  4. 不用函数库求一个数的平方根 (java版)

    一.题目 编写程序求一个整数的平方根,精确到小数点后三位 二.解法 1) 采用 牛顿迭代法. 2)牛顿迭代法简介 假设方程 在  附近有一个根,那么用以下迭代式子:                  ...

  5. 一篮子苹果,每天吃一半多一个吃,第十天吃一半多一个后就剩余一个,求一共多少个苹果,JAVA版

    /** * @author xuzhu **/public class TestApple { public static void main(String[] args) { int days = ...

  6. 【SICP读书笔记(五)】练习2.32 --- 递归求集合子集

    题目内容: 我们可以将一个集合表示为一个元素互不相同的表,因此就可以将一个集合的所有子集表示为表的表.例如,假定集合为(1,2,3),它的所有子集的集合就是( () (3) (2) (2 3) (1) ...

  7. 【转载】 C#使用Union方法求两个List集合的并集数据

    在C#语言的编程开发中,有时候需要对List集合数据进行运算,如对两个List集合进行交集运算或者并集运算,其中针对2个List集合的并集运算,可以使用Union方法来快速实现,Union方法的调用格 ...

  8. 【转载】C#编程中两个List集合使用Intersect方法求交集

    在C#语言程序设计中,List集合是常用的集合数据类型,在涉及集合类型的运算中,有时候我们需要计算2个List集合中共有的数据,即对2个List集合求交集运算.此时可以使用C#语言提供的Interse ...

  9. 【转载】C#使用Except方法求取两个List集合的差集数据

    在C#语言的编程开发中,针对List集合的运算有时候需要计算两个List集合的差集数据,集合的差集是取在该集合中而不在另一集合中的所有的项.A集合针对B集合的差集数据指的是所有在A集合但不在B集合的元 ...

随机推荐

  1. Counting Haybales (线段树)

    Counting Haybales 时间限制: 50 Sec  内存限制: 256 MB提交: 52  解决: 18[提交][状态][讨论版] 题目描述 Farmer John is trying t ...

  2. 16、Django实战第16天:优化url

    今天完成的是一个优化url.... 前面我们所有的url都是配置在一个mxonline.urls.py中.因为我们根据项目实际情况配置了多个app,那么我们相应的url是可以配置在自己的app中的,这 ...

  3. AGC 025 B - RGB Coloring

    B - RGB Coloring Time limit : 2sec / Memory limit : 1024MB Score : 700 points Problem Statement Taka ...

  4. 5.8 Properties

    一.Propertie 主要用于读写资源配置文件. Properties继承自Hashtable. 我们来看下HashMap和Hashtable的区别: Hashtabl  线程安全,    同步,  ...

  5. map泛型 map不指定泛型 与 Map<Object,Object>的区别

    map泛型 map不指定泛型 与 Map<Object,Object>的区别 private void viewDetail(){ Map map1 = new HashMap(); Ma ...

  6. [OpenJudge8471][划分DP]切割回文

    切割回文 总时间限制: 1000ms 内存限制: 65536kB [描述] 阿福最近对回文串产生了非常浓厚的兴趣. 如果一个字符串从左往右看和从右往左看完全相同的话,那么就认为这个串是一个回文串.例如 ...

  7. Mapper动态代理开发

    在开发的过程中只需要写Dao层的借口,无需写其实现类,实现类有框架自己补充. 框架是根据mapper文件自动补充的,因此需要满足下面四个条件 Mapper接口开发需要遵循以下规范: Mapper.xm ...

  8. 51单片机软件I2C驱动中的CY

    做一个MSP430的项目,虽然430内部有硬件I2C的模块,略难,准备直接移植51的..碰到一句代码 dat <<= 1; //移出数据的最高位 pSDA = CY; //送数据口 dig ...

  9. CSS3:3D转换

    几个突破口:(为了更简洁理解,先忽略兼容) 1.认识3D的坐标系 rotateX()-----------元素绕X轴旋转 rotateY() -----------元素绕Y轴旋转 rotateZ() ...

  10. 设置cookie和查找cookie的方法

    1.设置cookie(名称,值,过期时间) function setCookie(key,value,d){ if(d === undefined){ document.cookie = encode ...