遞歸控制-列出所有組合
阿新 • • 發佈:2018-11-29
info list() str image 測試 入參 void 結果 tin
0.目錄
1.遞歸思路
2.Java代碼實現
- 2.1 分開考慮初始值
- 2.2 合並各自初始條件
- 2.3 維護side-effect
- 2.4 測試用例
1.遞歸思路
列出所有組合,例如從1,2,3,4中任取2個元素,求出所有的組合。
面對combinations([1,2,3,4], 2):
遞歸思路為:
- 選1 → combinations([2,3,4], 1)
不選1 → combinations([2,3,4], 2)
2.Java代碼實現
2.1 分開考慮初始值
先分開考慮傳入參數的初始值
/** * Generates all combinations and output them, * selecting n elements from data */ public void combinations(List<Integer> data, int n) { // initial value for recursion if (data.isEmpty()) { if (n == 0) { // output empty list } return; } if (n < 0) { return; } if (n == 0) { // output empty list return; } // select element 0 combinations(data.subList(1, data.size()), n - 1); // un-select element 0 combinations(data.subList(1, data.size()), n); }
2.2 合並各自初始條件
合並初始值條件後,考慮兩個問題:
如何選擇元素?如何輸出?
/** * Generates all combinations and output them, * selecting n elements from data */ public void combinations(List<Integer> data, int n) { // how to select elements // how to output if (n == 0) { // output all selected elements return; } if (data.isEmpty()) { // output empty list return; } // select element 0 combinations(data.subList(1, data.size()), n - 1); // un-select element 0 combinations(data.subList(1, data.size()), n); }
2.3 維護side-effect
維護一個selected,也就是之前所選擇的的所有元素。
/** * Generates all combinations and output them, * selecting n elements from data */ public void combinations( List<Integer> selected, List<Integer> data, int n) { if (n == 0) { // output all selected elements for (Integer i : selected) { System.out.print(i); System.out.print(" "); } System.out.println(); return; } if (data.isEmpty()) { // output empty list return; } // select element 0 selected.add(data.get(0)); combinations(selected, data.subList(1, data.size()), n - 1); // un-select element 0 selected.remove(selected.size() - 1); combinations(selected, data.subList(1, data.size()), n); }
2.4 測試用例
測試程序是否正確運行:
public static void main(String[] args) {
Combinations comb = new Combinations();
comb.combinations(
new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 2);
}
運行結果為
多測幾個極端用例
public static void main(String[] args) {
Combinations comb = new Combinations();
comb.combinations(
new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 2);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(), 2);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(), 0);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 1);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 0);
System.out.println("=================");
}
運行結果為
全部代碼:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Combinations {
/**
* Generates all combinations and output them,
* selecting n elements from data
*/
public void combinations(
List<Integer> selected, List<Integer> data, int n) {
if (n == 0) {
// output all selected elements
for (Integer i : selected) {
System.out.print(i);
System.out.print(" ");
}
System.out.println();
return;
}
if (data.isEmpty()) {
// output empty list
return;
}
// select element 0
selected.add(data.get(0));
combinations(selected, data.subList(1, data.size()), n - 1);
// un-select element 0
selected.remove(selected.size() - 1);
combinations(selected, data.subList(1, data.size()), n);
}
public static void main(String[] args) {
Combinations comb = new Combinations();
comb.combinations(
new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 2);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(), 2);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(), 0);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 1);
System.out.println("=================");
comb.combinations(
new ArrayList<>(), Arrays.asList(1, 2, 3, 4), 0);
System.out.println("=================");
}
}
遞歸控制-列出所有組合