例如:
String[] str = {"a" , "b" ,"c"};
想要得到
{"", "a", "b", "c", "ab", "abc", "bc", "ac" };
或者
{"a", "b", "c", "ab", "abc", "bc", "ac" };
这样的组合。
求全组合,当假设原有元素n个,则最终组合结果是2^n个。
原因是:
用位操作方法:假设元素原本有:a,b,c三个,则1表示取该元素,0表示不取。取a时是001,取ab时是011.
一共三位,每个位上有两个选择0或者1.所以是2^n个结果。
将1分别左移a, b, c的下标0,1,2位得到1,2,4再分别与0,1,2,3,4,5,6,7进行&
运算,当其!=0
时,取其位置元素。
(i=0)&tmp={1,2,4} | Value |
---|---|
000&001 | 0 |
000&010 | 0 |
000&100 | 0 |
(i=1)&tmp={1,2,4} | Value |
---|---|
001&001 | 1 !=0 取a |
001&010 | 0 |
001&100 | 0 |
(i=2)&tmp={1,2,4} | Value |
---|---|
010&001 | 0 |
010&010 | 1 !=0 取b |
010&100 | 0 |
(i=3)&tmp={1,2,4} | Value |
---|---|
011&001 | 1 !=0 取a |
011&010 | 2 !=0 取b |
011&100 | 0 |
(i=4)&tmp={1,2,4} | Value |
---|---|
100&001 | 0 |
100&010 | 0 |
100&100 | 1 !=0 取c |
(i=5)&tmp={1,2,4} | Value |
---|---|
101&001 | 1 !=0 取a |
101&010 | 0 |
101&100 | 1 !=0 取c |
(i=6)&tmp={1,2,4} | Value |
---|---|
110&001 | 0 |
110&010 | 2 !=0 取b |
110&100 | 4 !=0 取c |
(i=7)&tmp={1,2,4} | Value |
---|---|
111&001 | 1 !=0 取a |
111&010 | 2 !=0 取b |
111&100 | 4 !=0 取c |
将所有表格汇总到一块就是
& | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
001 | !=0 取a | 0 | !=0 取a | 0 | !=0 取a | 0 | !=0 取a |
010 | 0 | !=0 取b | !=0 取a | 0 | 0 | !=0 取b | !=0 取b |
100 | 0 | 0 | 0 | !=0 取c | !=0 取c | !=0 取c | !=0 取c |
a | b | ab | c | ac | bc | abc |
得到
{"", "a", "b", "c", "ab", "abc", "bc", "ac" };
当i=1
开始时候,得到
{"a", "b", "c", "ab", "abc", "bc", "ac" };
代码
public static void Combination() {
String[] str = {"a", "b", "c"};
int n = str.length; //元素个数。
int nbit = 1 << n; // “<<” 表示 左移
System.out.println("全组合结果个数为:" + nbit);
for (int i = 0; i < nbit; i++) {
//结果有nbit个。输出结果从数字小到大输出:即输出0,1,2,3,....2^n。
//for(int i=1 ;i<nbit ; i++) { 去掉空元素
System.out.print("组合数值 " + i + " 对应编码为: ");
for (int j = 0; j < n; j++) {
int tmp = 1 << j;
if ((tmp & i) != 0) {
System.out.print(str[j]);
}
}
System.out.println();
}
}
结果
全组合结果个数为:8
组合数值 0 对应编码为:
组合数值 1 对应编码为: a
组合数值 2 对应编码为: b
组合数值 3 对应编码为: ab
组合数值 4 对应编码为: c
组合数值 5 对应编码为: ac
组合数值 6 对应编码为: bc
组合数值 7 对应编码为: abc