有5个球(A B C D E),先要从中选出3个,求所有可能的情况。
思路:
对于每个球,只有两种状态,选择与非选择
从A球开始,如果选择了A球,则需要从剩下的(B C D E)球中选择2个球
如果不选A球,则需要从剩下的(B C D E)球中选择3个球
分别继续递归,知道待选的球数目为0
Java版代码:
public class Combination { public static void main(String[] args) { String str = "abcde"; // combination(str, 3); getAllCombinations(str); } public static void combination(String s, int num) { if (s == null) return; if (num < 0 || num > s.length()) num = s.length(); boolean[] arr = new boolean[s.length()]; int[] cnt = new int[1]; _combination(s, 0, num, arr, cnt); System.out.println("组合总数:" + cnt[0]); } public static void getAllCombinations(String s) { int num = s.length(); int[] cnt = new int[1]; boolean[] arr = new boolean[num]; for (int i = 1; i <= num; ++i) { System.out.println(i + "位数的组合"); _combination(s, 0, i, arr, cnt); for (int j = 0; j < num; ++j) { arr[j] = false; } } } // leftNum表示剩余要选择的数字, arr用来记录对应位置是否已经被使用 // cnt用于统计总数的次数 private static void _combination(String s, int start, int leftNum, boolean[] arr, int[] cnt) { if (leftNum == 0) { for (int i = 0; i < start; ++i) { if (arr[i] == true) { System.out.print(s.charAt(i)); } } System.out.println(); cnt[0]++; return; } if (start == s.length()) return; arr[start] = true; //选取第k位,则从start+1位开始,还剩下leftNum-1待选 _combination(s, start + 1, leftNum - 1, arr, cnt); arr[start] = false; //不选取第k位,则从start+1位开始,还剩下leftNum待选 _combination(s, start + 1, leftNum, arr, cnt); } }
效果:
1位数的组合
a
b
c
d
e
2位数的组合
ab
ac
ad
ae
bc
bd
be
cd
ce
de
3位数的组合
abc
abd
abe
acd
ace
ade
bcd
bce
bde
cde
4位数的组合
abcd
abce
abde
acde
bcde
5位数的组合
abcde