求一个集合的子集有很多方法,这里用的是组合数学里的方法。
import java.util.*;
public class Test_subset {
/**
* @param args
*/
int n = 4;
int m = 1 << n;
public List<List<Integer>> subset(int n, int[] sub)
{
int s[][] = new int[1 << n][n];
for (int i = 1; i < (1 << n) - 1; i++) {
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) == 0) {
s[i - 1][j] = 0;
} else {
s[i - 1][j] = 1;
}
}
}
List<List<Integer>> subSet = new ArrayList<List<Integer>>();
for (int i = 0; i < (1 << n) - 2; i++) {
List<Integer> temp = new ArrayList<Integer>();
for (int j = 0; j < n; j++) {
if (s[i][j] == 1)
temp.add(sub[j]);
}
subSet.add(temp);
}
return subSet;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Test_subset sub = new Test_subset();
int set[] = { 1, 2, 3, 4 };
List<List<Integer>> ls = sub.subset(4, set);
for (List<Integer> temp1 : ls)
System.out.println(temp1);
}
}
这里求的是非空真子集,真子集是除去全集的情况;非空真子集是出去空集的情况;所以有2^n -2种情况。i从2取到(1 << n) - 1。
结果如下:
[1]
[2]
[1, 2]
[3]
[1, 3]
[2, 3]
[1, 2, 3]
[4]
[1, 4]
[2, 4]
[1, 2, 4]
[3, 4]
[1, 3, 4]
[2, 3, 4]