一个包含n个元素的集合,获取其所有子集,可以采用按位对应法,例如:
int[] array = {1, 3, 2, 5};
这个集合可以看做1325四位,每一位在子集中要么存在要么不存在,是否的操作我们就考虑二进制的01:
一位子序列的情况有: 1000 0100 0010 0001 ——》{1} {3} {2} {5}
二位子序列情况有: 1100 1010 1001 0110 0101 0011 ——》{1,3} {1,2} {1,5} {3,2} {3,5} {2,5}
三位子序列情况: 1110 1011 1101 0111 ——》{1,3,2} {1,2,5} {1,5,3} {3,2,5}
四位子序列情况 :1111——》{1,3,2,5}
空子序列: 0000——》{}
4位每一位都有存在不存在两种可能,那么总共是2的4次幂中可能,遍历每一种可能去除存在的数组的元素即为该种情况的子集
/**
* 位对应法
*
* @param array
*/
public void place(int[] array) {
//获取数据长度 那么对应的就是二进制字节位数1存在 0不存在 假设长度为4
//一位子序列的情况有 1000 0100 0010 0001
//二位子序列情况有 1100 1010 1001 0110 0101 0011
//三位子序列情况 1110 1011 1101 0111
//四位子序列情况 1111
//空子序列 0000
int length = array.length;
//二进制的可能情况数量为1向左移动数组长度位数,为什么呢?因为总共是3位
// 每一个存在不存在两种可能 所以就是2的4次方种情况
int end = 1 << length;
int mark = 0;//标记
//打印出每一种情况的子序列
for (mark = 0; mark < end; mark++) {
boolean isNUll = true;
//遍历都不存在就是空子集
for (int i = 0; i < length; i++) {
if ((1 << i & mark) != 0) {//!=0存在 =0不存在
isNUll = false;
System.out.print(array[i] + ",");
}
}
if (isNUll) {
System.out.print("null");
}
System.out.println();
}
}
@Test
public void getAllChildren() {
int[] array = {1, 3, 2, 5};
place(array);
}
输出结果:
null
1,
3,
1,3,
2,
1,2,
3,2,
1,3,2,
5,
1,5,
3,5,
1,3,5,
2,5,
1,2,5,
3,2,5,
1,3,2,5,