给定随意长度的一个集合。用一个数组表示,如{"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. 字典树(Trie Tree)

    终于要开始更新我的ACM学习之路了,不过没想到却是因为一次Java大作业,有趣,%yuan老师. 字典树是一种很简单的树形结构,主要用来进行词频统计,在算法竞赛中有时也会碰到. 字典树的基本思路是,通 ...

  2. 训练指南 UVA- 11865(有向最小生成树 + 朱刘算法 + 二分)

    layout: post title: 训练指南 UVA- 11865(有向最小生成树 + 朱刘算法 + 二分) author: "luowentaoaa" catalog: tr ...

  3. JavaScript中的局部作用域及常量的定义

    局部作用域 通常JavaScript的作用域是函数内部,在类似for循环的语句块中是无法申明局部变量的. function exm() { for (var i=0; i<100; i++) { ...

  4. [Codeforces 26E] MultiThreading

    Brief Intro: 给你n个数,每个数有2*CNT[i]个,让你构造一个序列 使得最终的Y值为W(其余见题面) Solution: 就是一道纯构造的题目: 先把特殊情况特殊处理,接下来考虑一般情 ...

  5. Codeforces 915 G Coprime Arrays

    Discipntion Let's call an array a of size n coprime iff gcd(a1, a2, ..., an) = 1, where gcd is the g ...

  6. 【矩阵乘法】图中长度为k的路径的计数

    样例输入 4 2 0 1 1 0 0 0 1 0 0 0 0 1 1 0 0 0 样例输出 6 #include<cstdio> #include<vector> using ...

  7. [POI2018]Prawnicy

    题目大意: 有$n(n\le10^6)$个线段,每个线段覆盖的范围是$[l_i,r_i]$,要求从中选取$k(k\le10^6)$个线段使得这些线段覆盖范围的交集最大,求最大交集及任意一种方案. 思路 ...

  8. JNI之数组

    Array Operations -- 数组操作 1.GetArrayLength jsize GetArrayLength(JNIEnv *env, jarray array); Returns t ...

  9. VS2017安装错误:工作负荷不完整,未能安装包“sqlcmdlnutils,version=15.1.61703.130,chip=x64,language=zh-CN”。

    场景:已安装的VS2017维护安装MVC4时出现如下错误: 看问题描述是由于sqlcmdlnutils安装失败影响到其它组件的安装,于是单独下载此安装包进行安装,发现安装一切正常,继续维护VS2017 ...

  10. Ado.Net基础拾遗一:读取数据

    从数据库中读取数据: 使用DataReader对象从数据库中读取数据 首先需要添加几个命名空间 //需要添加的命名空间 using System.Configuration; using System ...