多個數組間元素排列組合交叉問題(Java實現)
阿新 • • 發佈:2019-02-08
所有可以用遞迴實現的操作都可以轉化為用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); } }
測試程式
//測試部分 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); } }
實現程式碼二
/** * 寫法二,遞迴計算所有組合 * @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); } }
測試程式
//測試部分
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()]);
}
迴圈法
優缺點:
採用迴圈方式程式編寫較遞迴法略複雜,但是執行效率高,不管陣列數量多少,都不會發生棧溢位。
程式碼
/**
* 演算法二,非遞迴計算所有組合
* @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);
}
測試程式
//測試部分
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);
}