public class test {
public static void main(String[] args) {
linkedList list = new linkedList<>(Arrays.asList("a","b","c"));
linkedList> result = new linkedList<>();
allCombination(list, result);
System.out.println(result);
}
public static void allCombination(List sourceList, List> result) {
int allCombinationNum = 1 << sourceList.size();
for (int i = 0; i < allCombinationNum; i++) {
linkedList resultChildList = new linkedList<>();
for (int j = 0; j < sourceList.size(); j++) {
if ((i & (1 << j)) != 0) {
resultChildList.add(sourceList.get(j));
}
}
result.add(resultChildList);
}
}
}
解析:
1. 确定全组合个数(循环次数及层级):
- 每个数字都有取或不取两种选择, 故共 2^sourceList.size() 种组合方式
- 可以按照位图值为sourceList角标来取值, [0, 2^sourceList.size()-1] 共2^sourceList.size()个数字
- 对应的输出结果为 [ , a, b , ba,c ,c a,cb ,cba]
- 每组值计算3次(对应二进制3位), 共2^sourceList.size()=8组
- 需要两层循环, 第一层循环分组(每一种组合为一组),需2^sourceList.size()次; 嵌套第二层循环计算每一组内元素,每组需sourceList.size()次
2. 判断每一组中需获取的元素(利用按位与"对应的两个二进位都为1,结果位就为1"的特性)
- 以sourceList中有3个元素为例, 第一层循环八次,0至8的"位值"为: [000,001,010,011,100,101,110,111], 四个元素则是[0000 至 1111]
- 当三个位分别为1时可视为a,b,c对应的值, 001=1=2^0=a, 010=2=2^1=b, 100=4=2^2=c, 指数0,1,2为二层循环序数
- 下面表格每一列即为全组合值
| 一层循环序数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 对应位 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
| 二层一次 | 001 | 001 | 001 | 001 | 001 | 001 | 001 | 001 |
| 按位与值 | 000 | 001 | 000 | 001 | 000 | 001 | 000 | 001 |
| 对应值 | a | a | a | a | ||||
| 二层二次 | 010 | 010 | 010 | 010 | 010 | 010 | 010 | 010 |
| 按位与值 | 000 | 000 | 010 | 010 | 000 | 000 | 010 | 010 |
| 对应值 | b | b | b | b | ||||
| 二层三次 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 按位与值 | 000 | 000 | 000 | 000 | 100 | 100 | 100 | 100 |
| 对应值 | c | c | c | c | ||||
| 最终组合 | a | b | ab | c | ac | bc | abc |



