所有可能的数组组合算法(匈牙利语,蛮力)

时间:2018-10-03 13:53:05

标签: javascript algorithm data-structures

有待解决的任务(对计算机视觉的人员跟踪),我以某种方式获得了2个数组的所有可能组合。 输入:两个数组

arr1 = ['a', 'b', 'c'];
arr2 = [1, 2, 3];

任务是编写(可能是递归的)算法以输出所有可能组合的数组,如下所示:

[
  {a:1, b:2, c:3},
  {a:1, b:3, c:2},
  {a:2, b:1, c:3},
  {a:2, b:3, c:1},
  {a:3, b:1, c:2},
  {a:3, b:2, c:1},
]

输入数组的长度可能不相同。例如

arr1 = [a,b];
arr2 = [1,2,3];
// => 
[
  {a:1, b:2},
  {a:1, b:3},
  {a:2, b:1},
  {a:2, b:3},
  {a:3, b:1},
  {a:3, b:2}
]

或者这样

arr1 = [a,b,c];
arr2 = [1,2];
// => 
[
  {a:1, b:2},
  {a:1, c:2},
  {b:1, a:2},
  {b:1, c:2},
  {c:1, a:2},
  {c:1, b:2}
]

完全是这样的结构

[
  {
    combo: {a:1, b:2, c:3}
  },
  ...
]

...但这并不重要

像这样的stackoverflow上有很多主题,但是所有这些算法都有些不同并且更容易。他们都给这样的东西:

[a1, a2, b1, b2, c1, c2]

到目前为止,我已经知道了:

const combos = (arr1, arr2, func) => {
    let result = [];
    for(let item1 of arr1){
        let subcombo = {};
        let subArr1 = Object.assign({}, arr1);
        delete subArr1[item1];
        for(let item2 of arr2){
            subcombo[item] = {};
        }
    }
};
function give1() {
    return 1;
}
let arr1 = ['a', 'b', 'c'];
let arr2 = ['x', 'y', 'z'];
const res = combos(arr1, arr2, give1);
console.log(res);

1 个答案:

答案 0 :(得分:1)

您可以首先创建函数以进行限制置换,然后根据键和值的长度进行键置换(如果keys.length > values.length进行值置换,否则进行值置换,然后根据该结果创建对象数组)。

function permute(data, len) {
  let result = []
  
  function generate(data, n, c) {
    if(!data.length) {
      result.push(c.slice(0, len));
      return;
    }
    
    for(var i = 0; i < data.length; i++) {
      c[n] = data[i]
      let copy = [...data]
      copy.splice(i, 1);
      generate(copy, n + 1, c)
    }
  }
  
  generate(data, 0, [])
  return result;
}

function f(keys, vals) {
  let byKeys = keys.length > vals.length,
  permuted = null
  
  if(byKeys) permuted = permute(keys, vals.length);  
  else permuted = permute(vals, keys.length);
  
  return permuted.map(arr => arr.reduce((r, e, i) => {
    byKeys ? r[e] = vals[i] :  r[keys[i]] = e
    return r;
  }, {}))
}

console.log(f(['a', 'b', 'c'], [1, 2, 3]))
console.log(f(['a', 'b', 'c'], [1, 2]))
console.log(f(['a', 'b'], [1, 2, 3]))