forked from shijiebei2009/Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Combination.java
81 lines (74 loc) · 3.47 KB
/
Combination.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package cn.codepub.algorithms.strings;
/**
* <p>
* Created with IntelliJ IDEA. 2015/10/30 21:43
* </p>
* <p>
* ClassName:Combination
* </p>
* <p>
* Description:组合:一般地,从m个不同的元素中,任取n(n≤m)个元素为一组,叫作从m个不同元素中取出n个元素的一个组合
* </P>
*
* @author Wang Xu
* @version V1.0.0
* @since V1.0.0
*/
public class Combination {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) {
char[] strs = new char[]{'a', 'b', 'c', 'd', 'e'};
for (int i = 1; i <= strs.length; i++) {
combination(strs, 0, i);
}
System.out.println("测试第二种方法");
combination();
}
/**
* 第一种方法
*
* @param strs 需要操作的字符数组
* @param start 从哪里开始取
* @param number 取几个字符
*/
public static void combination(char[] strs, int start, int number) {
//定义函数出口先
if (number <= 0 || start >= strs.length) {
System.out.println(sb.toString());
return;
}
//选取当前字符的话,需要将number-1
sb.append(strs[start]);
combination(strs, start + 1, number - 1);
//不选取当前字符的话,number不变
sb.deleteCharAt(sb.length() - 1);
//注意因为还需要从start+1的位置开始取number个字符,那么如果剩下的字符不足number就没必要去取了
if (strs.length - start > number) {
combination(strs, start + 1, number);
}
}
/**
* 第二种方法
* 基本思路:求全组合,则假设原有元素n个,则最终组合结果是2^n个。原因是: 用位操作方法:假设元素原本有:a,b,c三个,则1表示取该元素,0表示不取。故去a则是001,取ab则是011<br/>
* 所以一共三位,每个位上有两个选择0,1。所以是2^n个结果。这些结果的位图值都是0,1,2....2^n。所以可以类似全真表一样,从值0到值2^n依次输出结果:即:000,001,010,011,100,101,110,111<br/>
* 对应输出组合结果为:空,a,b,ab,c,ac,bc,abc. 这个输出顺序刚好跟数字0~2^n结果递增顺序一样 取法的二进制数其实就是从0到2^n-1的十进制数
*/
public static void combination() {
String[] str = {"a", "b", "c"};
int n = str.length; // 元素个数。
// 求出位图全组合的结果个数:2^n
int nbit = 1 << n; // “<<” 表示 左移:各二进位全部左移若干位,高位丢弃,低位补0。:即求出2^n=2Bit。
// System.out.println("全组合结果个数为:" + nbit + ",二进制:" + Integer.toBinaryString(nbit));
for (int i = 0; i < nbit; i++) { // 结果有nbit个。输出结果从数字小到大输出:即输出0,1,2,3,....2^n。
// System.out.print("组合数值 " + i + " 对应编码为: ");
for (int j = 0; j < n; j++) { // 每个数二进制最多可以左移n次,即遍历完所有可能的变化新二进制数值了
int tmp = 1 << j;
// System.out.println("->" + Integer.toBinaryString(tmp));
if ((tmp & i) != 0) { // & 表示与。两个位都为1时,结果才为1
System.out.print(str[j]);
}
}
System.out.println();
}
}
}