多個數組排列問題

有時候會有需求 從N個數組個各取1個元素組成新數組,問有多少種可能,分別是什麼?(這裏假設不涉及重複元素和順序影響)java

相似 [a,b,c,d],[1,2],[A,B,F] 3個數組個各取一個元素組成新數組,共計24種可能,結果分別以下:apache

[a,1,A],[a,1,B],[a,1,F],[a,2,A],[a,2,B],[a,2,F],[b,1,A],[b,1,B]......[d,2,A],[d,2,B],[d,2,F].數組

那如何用程序來完成這個數學問題呢?下面先介紹思路,再用java代碼嘗試code。測試

每次從3個數組中各取一個元素,取元素的下標初始默認分別是0->(0,0,0),即:第一個數組是"a",第二個數組是"1",第三個數組是"A"; 下一個新數組來源的下標呢?前2個仍是0,第三個加1->(0,0,1),同理,再下一個呢?(0,0,2),再下一個呢? 是0,0,3嗎?code

這裏須要注意一下,當取元素的數組的下標越界(>=當前數組的長度)時,咱們須要將當前元素的數組的下標置爲0,前一個數組的下標加1,因此(0,0,2)後面一個下標應該是(0,1,0);後面規律就同樣了。索引

看這個過程像什麼呢?是否是相似進制數+1的過程?get

若是是10進制的,2個數組就相似組成兩位數,3個數組相似組成3位數。可能性= 10*10*...*10,有多少個數組就有10N種可能數學

若是是2進制的,即,每一個源數組都有2個元素,那可能性=2*2*...*2 有多少個數組就有2N種可能;it

如今數組長度是不規律的,可能性= 每一個數組元素個數乘積,上方示例可能=4*2*3=24種;class

知道了過程和原理開始擼代碼吧:

給出的參數就是1個集合,集合的每一個元素是1個數組

List<String[]> originalList

首先須要2個臨時變量數組,分別存放原數組取數的下標和原數組的長度

int[] tempIndexArr = new int[originalList.size()];

int[] tempLengthArr = new int[originalList.size()];

須要1個集合存放新組成的數組

List<String[]> combineList = new ArrayList<>();

須要一個是否完成遍歷的flag

boolean completeFlag = false;

最核心的邏輯,其實也很簡單,就是取下標索引:

int changeIndex = originalList.size() - 1;

boolean isRightIndex = false;

while (!isRightIndex) {

    tempIndexArr[changeIndex] += 1;

    if(tempIndexArr[changeIndex] >= tempLengthArr[changeIndex]) {

        tempIndexArr[changeIndex--] = 0;

    } else {

        isRightIndex = true;

    }

}

取到了下標索引,從原集合中根據下標索引取數組成新數組放到新集合中

String[] newItem = new String[originalList.size()];

for (int i = 0; i < originalList.size() ; i++) {

    newItem[i] = originalList.get(i)[tempIndexArr[i]];

}

combineList.add(newItem);

基本過程就結束了。 不過這裏須要增長一個判斷 就是是否遍歷完了,判斷邏輯是 下標都已經到了最大值,完成代碼、測試和打印結果以下

package work;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

/**
 * @author lixiaoming
 * @date 2019/6/19 16:53
 */
public class CombineTest {

    public static void main(String[] args) {
        List<String[]> originalList = new ArrayList<>();
        originalList.add(new String[] {"a", "b", "c", "d"});
        originalList.add(new String[] {"1", "2"});
        originalList.add(new String[] {"A", "B", "F"});

        List<String[]> combineList = getCombineList(originalList);

        System.out.println("組成的新集合共有" + combineList.size() + "個數組");

        combineList.forEach(s-> {
            System.out.println(StringUtils.join(s, ","));
        });
    }

    private static List<String[]> getCombineList(List<String[]> originalList) {
        int originalSize = originalList.size();
        int[] tempIndexArr = new int[originalSize];
        tempIndexArr[originalSize - 1] = -1;
        int[] tempLengthArr = new int[originalSize];
        for (int i = 0; i < originalSize ; i++) {
            tempLengthArr[i] = originalList.get(i).length;
        }

        List<String[]> combineList = new ArrayList<>();
        boolean completeFlag = false;

        while(!completeFlag) {
            int changeIndex = originalList.size() - 1;
            boolean isRightIndex = false;
            while (!isRightIndex) {
                tempIndexArr[changeIndex] += 1;
                if(tempIndexArr[changeIndex] >= tempLengthArr[changeIndex]) {
                    if(changeIndex == 0) {
                        isRightIndex = true;
                        completeFlag = true;
                    } else {
                        tempIndexArr[changeIndex--] = 0;
                    }
                } else {
                    isRightIndex = true;
                }
            }
            if(isRightIndex && !completeFlag) {
                String[] newItem = new String[originalList.size()];
                for (int i = 0; i < originalList.size() ; i++) {
                    newItem[i] = originalList.get(i)[tempIndexArr[i]];
                }
                combineList.add(newItem);
            }
        }

        return combineList;
    }

}

打印結果以下:

組成的新集合共有24個數組

a,1,A

a,1,B

a,1,F

a,2,A

a,2,B

a,2,F

b,1,A

b,1,B

b,1,F

b,2,A

b,2,B

b,2,F

c,1,A

c,1,B

c,1,F

c,2,A

c,2,B

c,2,F

d,1,A

d,1,B

d,1,F

d,2,A

d,2,B

d,2,F

Process finished with exit code 0

相關文章
相關標籤/搜索