目标:查找m个数组的所有长度为n的组合的集合,以使集合中每个项目的索引i与该集合的任何其他元素中的i不相同
我有以下数组:
array1 = ['a', 'b', 'c', 'd'];
array2 = ['e', 'f', 'g', 'h'];
array3 = ['i', 'j', 'k', 'l'];
array4 = ['m', 'n', 'o', 'p'];
我想找到每个数组中每个元素的所有可能组合,然后将这些组合放入集合中,以使给定集合中任何元素的索引 i 与索引<同一组中另一个元素的em> 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'与array2
不同,等等。
现在我需要找到所有可能的其中一种。
我尝试查看this帖子并通过创建组合组合来实现它,然后过滤掉所有无效内容并循环遍历以建立集合,但是当然这错过了很多,花了将近一个小时来运行例。因此,我需要一种更系统的方法来加快过程并使其更整洁。
答案 0 :(得分:0)
您基本上想找到每个数组的每个排列并将它们组合。这可以递归完成:
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);