遞歸解決一種排列組合的方法

問題場景:

好比說一件商品有3中屬性,每一個屬性又有3種不一樣的值,那麼此時問,這幾種屬性可能的組合性,相信你很快就獲得結果爲"333=27"種,此時你能夠實現的方式能夠爲三個for循環嵌套來實現,那麼若是場景變了,若是是4種屬性,那你可能就要4個for循環,那麼若是此時又變成10個,那是否是要用10個循環了,此時的代碼就顯得笨重而且不易讀,因此此時咱們就能夠用遞歸實現此業務場景。**算法

解決思路:

一、能夠將相同屬性的值放到一個List中,規定一個List的子類,如ArrayList,將全部的相同屬性值都放到一個ArrayList中去,此時有多少個屬性就能夠獲得多少個封裝了相同屬性值的ArrayList。
二、將上述生成的全部的ArrayList都放到個List中,即List<ArrayList<?>>;
三、而後將上述List中的ArrayList順序兩個組合成一個新的LinkedList,此處新List子類型是爲了和以前的ArrayList區分開來,以便後續區分對待。詳見代碼數組

代碼示例:
public class MainTest {
    
    private static List returnList = new ArrayList();
    public static void main(String[] args) {

        List<ArrayList<String>> stateLists = new ArrayList<ArrayList<String>>();
        ArrayList<String> als1 = new ArrayList<>();
        als1.add("Color_1");
        als1.add("Color_2");
        ArrayList<String> als2 = new ArrayList<>();
        als2.add("Style_1");
        als2.add("Style_2");
        ArrayList<String> als3 = new ArrayList<>();
        als3.add("Size_1");
        als3.add("Size_2");
        ArrayList<String> als4 = new ArrayList<>();
        als4.add("High_1");
        als4.add("High_2");
        stateLists.add(als1);
        stateLists.add(als2);
        stateLists.add(als3);
        stateLists.add(als4);

        addstatement(stateLists);
        System.out.println("returnList:"+returnList.size()+" "+returnList);
    }

    public static void addstatement(List<?> dataLists){

        int len=dataLists.size();
        //判斷List中的size是否小於2,若是小於說明已經遞歸完成了
        if (len<2){
            returnList=dataLists;
            return;
        }

        //第一個是 ArrayList 或 LinkedList()
        int len0 ;
        if(dataLists.get(0) instanceof  ArrayList<?>){
            len0 = ((ArrayList<String>)dataLists.get(0)).size();
        } else {
            len0 = ((LinkedList<String>)dataLists.get(0)).size();
        }
        int len1 ;
        //第二個必定是 ArrayList
        ArrayList<String> secondList = (ArrayList<String>)dataLists.get(1);
        len1 = ((ArrayList<String>)dataLists.get(1)).size();

        //定義臨時存放排列數據的集合默認的是ArrayList,新組合的是 LinkedList
        LinkedList<LinkedList<String>> tempdataLists=new LinkedList<>();

        //第一層for就是循環dataLists第一個元素的
        for (int i=0;i<len0;i++){
            //第二層for就是循環dataLists第二個元素的
            for (int j=0;j<len1;j++){
                //判斷第一個元素若是是ArrayList說明循環纔剛開始
                if (dataLists.get(0) instanceof ArrayList<?>){
                    ArrayList<String> arr0= (ArrayList<String>) dataLists.get(0);
                    // 建立LinkedList類型與ArrayList區分開來,用於將新的數據從新存儲
                    LinkedList<String> arr=new LinkedList<>();
                    arr.add(arr0.get(i));
                    arr.add(secondList.get(j));
                    //把排列數據加到臨時的集合中
                    tempdataLists.add(arr);
                } else {
                    //到這裏就明循環了最少一輪,即數據中只剩下兩個,一個是LinkedList,一個是ArrayList
                    LinkedList<LinkedList<String>> arrtemp= (LinkedList<LinkedList<String>>) dataLists.get(0);
                    LinkedList<String> arr=new LinkedList<>();
                    // 取出老的LinkedList數據賦值給新的LinkedList,同時把第二個ArrayList中的數據賦值給新的LinkedList
                    for (int k=0;k<arrtemp.get(i).size();k++){
                        arr.add(arrtemp.get(i).get(k));
                    }
                    arr.add(secondList.get(j));
                    tempdataLists.add(arr);
                }
            }
        }

        //這是根據上面排列的結果從新生成的一個集合
        List newdataLists=new ArrayList<>();
        //把還沒排列的數組裝進來,看清楚i=2的喔,由於前面兩個數組已經完事了,不須要再加進來了
        for (int i=2;i<dataLists.size();i++){
            newdataLists.add(dataLists.get(i));
        }
        //記得把咱們辛苦排列的數據加到新集合的第一位喔,否則白忙了
        newdataLists.add(0,tempdataLists);

        //你沒看錯,咱們這整個算法用到的就是遞歸的思想。
        addstatement(newdataLists);
    }
}
運行結果:

returnList:1 [[[Color_1, Style_1, Size_1, High_1], [Color_1, Style_1, Size_1, High_2], [Color_1, Style_1, Size_2, High_1], [Color_1, Style_1, Size_2, High_2], [Color_1, Style_2, Size_1, High_1], [Color_1, Style_2, Size_1, High_2], [Color_1, Style_2, Size_2, High_1], [Color_1, Style_2, Size_2, High_2], [Color_2, Style_1, Size_1, High_1], [Color_2, Style_1, Size_1, High_2], [Color_2, Style_1, Size_2, High_1], [Color_2, Style_1, Size_2, High_2], [Color_2, Style_2, Size_1, High_1], [Color_2, Style_2, Size_1, High_2], [Color_2, Style_2, Size_2, High_1], [Color_2, Style_2, Size_2, High_2]]]code

相關文章
相關標籤/搜索