采用[b]位[/b]掩码实现打印给定数组所有的非空子集。
[b]分析:[/b]
首先来看一个例子,如果给定一个正整数N,如何输出由1到N组成的数组所有的非空子集呢?
如N=3, 那么1到3组成的数组为{1,2,3},数组长度为3,那么二进制表示有[b]1<<3 = 8[/b]种。
0 = 000 = {} 空集
1 = 001 = {1}
2 = 010 = {2}
3 = 011 = {1, 2}
4 = 100 = {3}
5 = 101 = {1, 3}
6 = 110 = {2, 3}
7 = 111 = {1, 2, 3}
[b]遍历所有的二进制表达式,考虑其中1的位置,并打印相应的值,就能得到我们想要的结果。[/b]
代码如下:
依据上述例子的实现方式,下面的方法实现打印一个字符串数组所拥有的所有非空子集。
具体的代码和简单的测试如下:
输出结果:
a
b
a b
c
a c
b c
a b c
1
2
1 2
3
1 3
2 3
1 2 3
[b]分析:[/b]
首先来看一个例子,如果给定一个正整数N,如何输出由1到N组成的数组所有的非空子集呢?
如N=3, 那么1到3组成的数组为{1,2,3},数组长度为3,那么二进制表示有[b]1<<3 = 8[/b]种。
0 = 000 = {} 空集
1 = 001 = {1}
2 = 010 = {2}
3 = 011 = {1, 2}
4 = 100 = {3}
5 = 101 = {1, 3}
6 = 110 = {2, 3}
7 = 111 = {1, 2, 3}
[b]遍历所有的二进制表达式,考虑其中1的位置,并打印相应的值,就能得到我们想要的结果。[/b]
代码如下:
/**
*
* 给定一个正整数N,输出由1到N组成的数组所有的非空子集。
* 如N=3, 那么1到3组成的数组为{1,2,3}
*
* 所有二进制的情况
*
* 0 = 000 = {} 空集
* 1 = 001 = {1}
* 2 = 010 = {2}
* 3 = 011 = {1, 2}
* 4 = 100 = {3}
* 5 = 101 = {1, 3}
* 6 = 110 = {2, 3}
* 7 = 111 = {1, 2, 3}
*
*/
public void printAllSubsets(int N) {
if (N <=0) {
throw new IllegalArgumentException("参数应该是一个正整数。");
}
int allMasks = 1 << N;
//如考虑空集 ,那么i的初始值为0
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < N; j++)
if ((i & (1 << j)) > 0)
System.out.print((j + 1) + " ");
System.out.println();
}
}依据上述例子的实现方式,下面的方法实现打印一个字符串数组所拥有的所有非空子集。
/**
* 打印一个数组所有的非空子集
*/
public void printAllSubsets(String[] array) {
if (null == array || 0 == array.length) {
throw new IllegalArgumentException("数组不能为Null,至少有一个元素");
}
// 数组长度
int len = array.length;
// 根据数据的长度,得出所有二进制的个数
// 如len =2;
// 0 = 00 = {}
// 1 = 01 = {1}
// 2 = 10 = {2}
// 3 = 11 = {1, 2}
int allMasks = 1 << len;
// 遍历所有的二进制表示方式
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < len; j++)
if ((i & (1 << j)) > 0)
System.out.print(array[j] + " ");
System.out.println();
}
}具体的代码和简单的测试如下:
public class PrintAllNonEmptySubsets {
/**
*
* 给定一个正整数N,输出由1到N组成的数组所有的非空子集。
* 如N=3, 那么1到3组成的数组为{1,2,3}
*
* 所有二进制的情况
*
* 0 = 000 = {} 空集
* 1 = 001 = {1}
* 2 = 010 = {2}
* 3 = 011 = {1, 2}
* 4 = 100 = {3}
* 5 = 101 = {1, 3}
* 6 = 110 = {2, 3}
* 7 = 111 = {1, 2, 3}
*
*/
public void printAllSubsets(int N) {
if (N <=0) {
throw new IllegalArgumentException("参数应该是一个正整数。");
}
int allMasks = 1 << N;
//如考虑空集 ,那么i的初始值为0
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < N; j++)
if ((i & (1 << j)) > 0)
System.out.print((j + 1) + " ");
System.out.println();
}
}
/**
* 打印一个数组所有的非空子集
*/
public void printAllSubsets(String[] array) {
if (null == array || 0 == array.length) {
throw new IllegalArgumentException("数组不能为Null,至少有一个元素");
}
// 数组长度
int len = array.length;
// 根据数据的长度,得出所有二进制的个数
// 如len =2;
// 0 = 00 = {}
// 1 = 01 = {1}
// 2 = 10 = {2}
// 3 = 11 = {1, 2}
int allMasks = 1 << len;
// 遍历所有的二进制表示方式
for (int i = 1; i < allMasks; i++) {
for (int j = 0; j < len; j++)
if ((i & (1 << j)) > 0)
System.out.print(array[j] + " ");
System.out.println();
}
}
public static void main(String[] args) {
PrintAllNonEmptySubsets exam = new PrintAllNonEmptySubsets();
exam.printAllSubsets(new String[] { "a", "b", "c" });
exam.printAllSubsets(3);
}
}输出结果:
a
b
a b
c
a c
b c
a b c
1
2
1 2
3
1 3
2 3
1 2 3
本文介绍了一种利用位掩码技术打印数组所有非空子集的方法,包括整数数组和字符串数组。通过遍历所有可能的二进制组合来确定子集中的元素。
1554

被折叠的 条评论
为什么被折叠?



