多個數組間元素排列組合問題求解(Java實現) 標籤: 遞迴排列組合迴圈
阿新 • • 發佈:2019-02-17
所有可以用遞迴實現的操作都可以轉化為用while、for等迴圈實現。
遞迴法
優缺點:
陣列數量不太多時用遞迴法確實使程式比較簡潔,陣列數量太多時遞迴函式棧過大,有可能導致執行時棧溢位。而且相對常用的演算法如普通迴圈等,執行效率較低。
實現程式碼一
/**
* 寫法一,遞迴計算所有組合
* @param inputList 所有陣列的列表
* */
public List<String> combination(List<String> inputList){
List<String> resList = new ArrayList<>();
combinationInt(inputList, resList, 0,
new char[inputList.size()]);
return resList;
}
private void combinationInt(List<String> inputList, List<String> resList,
int ind, char[] arr) {
if(ind == inputList.size()){
resList.add(new String(arr));
return;
}
for(char c: inputList.get(ind).toCharArray()){
arr[ind] = c;
combinationInt(inputList, resList, ind + 1, arr);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
測試程式
//測試部分
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("ab");
list.add("12");
list.add("AB");
List<String> result=combination(list);
System.out.println("組合結果:");
for (String string : result) {
System.out.println(string);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
實現程式碼二
/**
* 寫法二,遞迴計算所有組合
* @param inputList 所有陣列的列表,陣列用List<Integer>儲存
* @param beginIndex 代表每一個數組的在inputList中的索引
* @param arr 用於儲存每一次遞迴生成的組合
* */
public void calculateCombination(List<List<Integer>> inputList, int beginIndex, int[] arr) {
if(beginIndex == inputList.size()){
//在這裡進行你自己的處理,比如列印組合的結果
for (int i : arr) {
System.out.print(i+", ");
}
System.out.println();
return;
}
for(int c: inputList.get(beginIndex)){
arr[beginIndex] = c;
calculateCombination(inputList, beginIndex + 1, arr);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
測試程式
//測試部分
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
list1.add(0);
list1.add(1);
list1.add(2);
List<Integer> list2 = new ArrayList<>();
list2.add(3);
list2.add(4);
list2.add(5);
List<Integer> list3 = new ArrayList<>();
list3.add(6);
list3.add(7);
list3.add(8);
List<List<Integer>> allList = new ArrayList<>();
allList.add(list1);
allList.add(list2);
allList.add(list3);
calculateCombination(allList, 0, new int[allList.size()]);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
迴圈法
優缺點:
採用迴圈方式程式編寫較遞迴法略複雜,但是執行效率高,不管陣列數量多少,都不會發生棧溢位。
程式碼
/**
* 演算法二,非遞迴計算所有組合
* @param inputList 所有陣列的列表
* */
public void calculateCombination(List<List<Integer>> inputList) {
List<Integer> combination = new ArrayList<Integer>();
int n=inputList.size();
for (int i = 0; i < n; i++) {
combination.add(0);
}
int i=0;
boolean isContinue=false;
do{
//列印一次迴圈生成的組合
for (int j = 0; j < n; j++) {
System.out.print(inputList.get(j).get(combination.get(j))+", ");
}
System.out.println();
i++;
combination.set(n-1, i);
for (int j = n-1; j >= 0; j--) {
if (combination.get(j)>=inputList.get(j).size()) {
combination.set(j, 0);
i=0;
if (j-1>=0) {
combination.set(j-1, combination.get(j-1)+1);
}
}
}
isContinue=false;
for (Integer integer : combination) {
if (integer != 0) {
isContinue=true;
}
}
}while (isContinue);
}
- 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
測試程式
//測試部分
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
list1.add(0);
list1.add(1);
list1.add(2);
List<Integer> list2 = new ArrayList<>();
list2.add(3);
list2.add(4);
list2.add(5);
List<Integer> list3 = new ArrayList<>();
list3.add(6);
list3.add(7);
list3.add(8);
List<List<Integer>> allList = new ArrayList<>();
allList.add(list1);
allList.add(list2);
allList.add(list3);
calculateCombination(allList);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20