[土味]Java遍历无序全排列组合
Java遍历无序全排列组合
在做迷宫生成,拆墙时需要用到无序的全排列,网上找到一段代码,也没有注释,看不懂,自己研究了下,把分析过程贴出来.
先上代码
/**
* 方法一:无序
*
* @param data
* @param <E>
* @return
*/
public static <E> List<List<E>> arrangeSelect1(List<E> data) {
int size = data.size();
// 一共 2^size-1 个无序全排列组合
int count = (int) (Math.pow(2, size) - 1);
List<List<E>> arrangeAllSet = new ArrayList<>();
for (int i = 1; i <= count; i++) {
List<E> arrangeSet = new ArrayList<>();
for (int j = 0; j < size; j++) {
if ((i << (31 - j)) >> 31 == -1) {
arrangeSet.add(data.get(j));
}
}
arrangeAllSet.add(arrangeSet);
}
return arrangeAllSet;
}
@Test
public void test() {
List<Integer> data = new ArrayList<Integer>();
for(int i=0; i<3; i++) {
data.add(i);
}
List<List<Integer>> arrangeList1 = arrangeSelect1(data);
System.out.println(arrangeList1);
}
他这边主要用到了左移和右移,特点如下
<< 左移,丢弃最高位(符号位同样丢弃),0补最低位
>> 右移 符号位不变,左边补上符号位
下面上分析过程
int a = 1;
0x00000001 (1的16进制)
0000 0000 0000 0000 0000 0000 0000 0001 (1的二进制)
执行 1 << 31
1000 0000 0000 0000 0000 0000 0000 0000
执行 1 << 31 >> 1
1100 0000 0000 0000 0000 0000 0000 0000
执行 1 << 31 >> 2
1110 0000 0000 0000 0000 0000 0000 0000
执行 1 << 31 >> 31 = -1
1111 1111 1111 1111 1111 1111 1111 1111
执行 1 << 10
0000 0000 0000 0000 0000 0100 0000 0000
执行 1 << 10 >> 31 = 0
0000 0000 0000 0000 0000 0000 0000 0000
结论: 对于1来说,只有一种情况可以让表达式 1 << (31 - j)) >> 31 == -1 成立,就是 j=0
对于2,3,4,5…来说,也可以用同样的方法得到 j 的取值,结果如下:
i 表达式 | j 取值 |
---|---|
1 << 31 >> 31 = -1 | j=0 |
2 << 30 >> 31 = -1 | j=1 |
3 << 31 >> 31 = -1 | j=0 |
3 << 30 >> 31 = -1 | j=1 |
4 << 29 >> 31 = -1 | j=2 |
5 << 31 >> 31 = -1 | j=0 |
5 << 29 >> 31 = -1 | j=2 |
6 << 30 >> 31 = -1 | j=1 |
6 << 29 >> 31 = -1 | j=2 |
7 << 31 >> 31 = -1 | j=0 |
7 << 30 >> 31 = -1 | j=1 |
7 << 29 >> 31 = -1 | j=2 |
8 << 28 >> 31 = -1 | j=3 |
-
横向看,可以看到数字3对应的 j 有两种情况,7有3种,其实可以看成3 = 1 + 2, 3的表达式是有1和2的表达式组合起来的,同样7 = 1 + 2 + 4,所以7的表达式就是1,2,4的表达式组合起来的.
-
纵向看 j取值列,可以发现,
第一行是1个元素{0}的全排列{0},
第1-4行是两个元素{0, 1}的全排列{[0],[1],[0,1]},
第1-12行是3个元素{0, 1, 2}的全排列{[0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2]} -
所以通过 i 和 j 的两重循环,就可以将所有的无序排列组合全部打印出来.
上一篇: Maven之Scope详解