打印一个数组所有的非空子集

本文介绍了一种利用位掩码技术打印数组所有非空子集的方法,包括整数数组和字符串数组。通过遍历所有可能的二进制组合来确定子集中的元素。
采用[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]

代码如下:

/**
*
* 给定一个正整数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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值