簡體   English   中英

查找長度為n的m個數組的所有集合

[英]Find all sets of length n combinations of m arrays

目標:查找長度為n個m數組組合的所有集合,以使集合中每個項目的索引i與該集合中任何其他元素的i不相同

我有以下數組:

array1 = ['a', 'b', 'c', 'd'];
array2 = ['e', 'f', 'g', 'h'];
array3 = ['i', 'j', 'k', 'l'];
array4 = ['m', 'n', 'o', 'p'];

我想找到來自每個陣列的這些服用一種元素的每個可能的組合,但隨后的那些組合放入集合,使得在一組給定的任何元素的索引i是在同一組的另一元件的索引i不同。 例如,一組可能是:

[ 
  { 1: "a", 2: "e", 3: "i", 4: "m" }, 
  { 1: "b", 2: "f", 3: "j", 4: "n" }, 
  { 1: "c", 2: "g", 3: "k", 4: "o" }, 
  { 1: "d", 2: "h", 3: "l", 4: "p" }
]

由於每個屬性'1'都不相同且取自array1 ,因此每個屬性'2'均不同且取自array2array2

現在,我需要找到其中的每一種可能。

我試着看過這篇文章,並通過創建組合的組合來實現它,然后過濾掉所有無效的內容並循環遍歷以建立集合,但是當然這錯過了很多,花了將近一個小時來運行此示例。 因此,我需要一種更系統的方法來加快過程並使其更整潔。

您基本上想找到每個數組的每個排列並將它們組合。 這可以遞歸完成:

function permutate(arr) {
    // every array of length one is already permutated
    if (arr.length == 1) return [ arr ];
    let permutations = [];
    for (let i = 0; i < arr.length; i++) {
        // Remove the current element and permutate the rest
        let sub = permutate(arr.splice(i, 1));
        // Insert current element into every permutation
        sub = sub.map(x => [arr[i], ...x]);
        // Add permutations to list
        permutations.push(...sub);
    }
    return permutations;
}

接下來的合並功能:

function combine(arrays, current = [], i = 0) {
    if (i == arrays.length)
        return [ current ];

    let values = [];

    for (let j = 0; j < arrays[i].length; j++) {
        let temp = current.slice();
        temp.push(arrays[i][j]);
        values.push(...combine(arrays, temp, i + 1));
    }

    return values;
}

// If you get a call stack size exceeded (stackoverflow) error, you can replace
// this using nested for loops. For instance for 5 arrays with 5 elements each:
let sets = [];
for (let i = 0; i < permutations[0].length; i++) {
  for (let j = 0; j < permutations[1].length; j++) {
    for (let k = 0; k < permutations[2].length; k++) {
      for (let l = 0; l < permutations[3].length; l++) {
        for (let m = 0; m < permutations[4].length; m++) {
            let set = [];
            for (let n = 0; n < 5; n++) {
                set.push([ permutations[0][i][n], permutations[1][j][n], permutations[2][k][n], permutations[3][l][n], permutations[4][m][n] ]);
            }
            sets.push(set);
        }
      }
    }
  }
}

通過首先排列每個數組(每個數組導致24個不同的排列),然后將它們組合(24 ^ 4 = 331776組合),您將獲得構造數組所需的一切。 只需遍歷每種組合,然后將相同索引處的元素放入同一集合中即可:

let permutations = [ array1, array2, array3, array4 ].map(arr => permutate(arr));

let sets = combine(permutations);
let out = [];
for (let i = 0; i < sets.length; i++) {
    let set = [];
    for (let j = 0; j < 4; j++) {
        set.push([ sets[i][0][j], sets[i][1][j], sets[i][2][j], sets[i][3][j] ]);
    }
    out.push(set);
}

工作示例:

 array1 = ['a', 'b', 'c', 'd']; array2 = ['e', 'f', 'g', 'h']; array3 = ['i', 'j', 'k', 'l']; array4 = ['m', 'n', 'o', 'p']; function permutate(arr) { if (arr.length == 1) return [ arr ]; let permutations = []; for (let i = 0; i < arr.length; i++) { let temp = arr.slice(); temp.splice(i, 1); let sub = permutate(temp); sub = sub.map(x => [arr[i], ...x]); permutations.push(...sub); } return permutations; } function combine(arrays, current = [], i = 0) { if (i == arrays.length) return [ current ]; let values = []; for (let j = 0; j < arrays[i].length; j++) { let temp = current.slice(); temp.push(arrays[i][j]); values.push(...combine(arrays, temp, i + 1)); } return values; } let permutations = [ array1, array2, array3, array4 ].map(arr => permutate(arr)); console.log(permutations); let sets = combine(permutations); let out = []; for (let i = 0; i < sets.length; i++) { let set = []; for (let j = 0; j < 4; j++) { set.push([ sets[i][0][j], sets[i][1][j], sets[i][2][j], sets[i][3][j] ]); } out.push(set); } console.log(out); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM