求一个集合的子集有很多方法,这里用的是组合数学里的方法。
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]