给定随意长度的一个集合。用一个数组表示,如{"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了。

最新文章

  1. VS2012配置OpenCV、GDAL开发环境
  2. Java提高篇——单例模式
  3. git 源代码下载和安装(CentOS)
  4. 游戏Loading中的小提示和Loading动画实现
  5. 2014 UESTC暑前集训图论专题解题报告
  6. 创建型模式(前引)简单工厂模式Simple Factory
  7. HDU-2509 Be the Winner
  8. Fedora24 升级到25
  9. Python Counter class
  10. 二分查找c++简单模板
  11. linux添加超级用户
  12. plsql调试存储过程卡住的原因以及处理
  13. [持续更新] 文章列表 Last Update: 8/21/2017
  14. loj 10001 种树
  15. react 子组件访问父组件的方法
  16. CentOS7添加入windows2008的AD域
  17. c#中partial 作用
  18. 解决 引入本地jar包后 maven无法编译的问题及部署war包缺失本地jar包的问题
  19. .NET基于Eleasticsearch搭建日志系统实战演练
  20. VSCode编辑器编写Python代码

热门文章

  1. Problem C: #104. 普通平衡树
  2. HDU 2162(注意初始化位置!)
  3. Counting Haybales (线段树)
  4. oracle enable / disable all constraint
  5. luogu P3368 【模板】树状数组 2
  6. [LOJ6437]PKUSC
  7. 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行
  8. 7.3(java学习笔记)网络编程之UDP
  9. [OpenJudge8786][暴力DP]方格取数
  10. iOS中用json接收图片的二进制流