繁体   English   中英

如何在不使用JavaScript的全局变量的情况下制作置换对?

[英]How to make permutaion pair without using global variable in JavaScript?

我需要创建一个由数组元素的所有可能组合组成的数组,例如排列变化广泛的数据结构问题。 要了解有关问题的更多信息,可以在随机黑客geeksforgeeks数学世界中查看。

注意:不想使用任何JS库,只是这里的数据结构

问题很简单,提供了一个数组,需要查找所有可能的组合,例如:

arr = [1,2,3];
combination = [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]];
// combination.length is factorial of arr.length

为此,我创建了一个全局变量来存储组合, 需要在没有全局变量的情况下执行此操作 ,但我无法做到这一点,任何人都可以帮助我弄清楚这一点,这是我的代码:

let ans = [];  // Global variable to store combinations

function permute(arr) {
  let l = arguments[1] || 0,
      r = arguments[2] || arr.length-1;

  if (l == r) {
    let a = [];

    a.push(...arr);  // To overcome reference problem here.
    ans.push(a);
  }
  else {
    for (let i = l; i <= r; i++) {
      [arr[l], arr[i]] = [arr[i], arr[l]];  // Swap with help of new destructuring
      permute(arr, l+1, r);
      [arr[l], arr[i]] = [arr[i], arr[l]];  // Swap with help of new destructuring
    }
  }

  return ans;
}

console.log(permute([1,2,3,4]));
console.log(permute([1,2,3]));
console.log(permute([1,2,3,4,5]));

感谢您的尝试和帮助。

您正在进行递归而没有通过累加器。 为减轻这种情况,请...

function permuteRecursive(permutees, accumulator) {
  // if not created before, create first instance of accumulator
  accumulator = accumulator || [];

  let l = arguments[2] || 0,
      r = arguments[3] || permutees.length-1;

  if (l == r) {
    let a = [];

    a.push(...permutees);  // To overcome reference problem here.
    accumulator.push(a);
  }
  else {
    for (let i = l; i <= r; i++) {
      [permutees[l], permutees[i]] = [permutees[i], permutees[l]];  // Swap with help of new destructuring
      permuteRecursive(permutees, accumulator, l+1, r);
      [permutees[l], permutees[i]] = [permutees[i], permutees[l]];  // Swap with help of new destructuring
    }
  }

  return accumulator;
}

console.log(permuteRecursive([1,2,3,4]));
console.log(permuteRecursive([1,2,3]));
console.log(permuteRecursive([1,2,3,4,5]));

我将使用附加参数将当前选定的元素传递给函数,并使用生成器将所有结果传递回:

 function* permutations(array, positions = [], previous = []) {
  if(previous.length === array.length) yield previous;

  for(let i = 0; i < array.length; i++) {
   if(positions.includes(i)) continue;

   const chosen = array[i];
   yield* permutations(array, [...positions, i], [...previous, chosen]);
  }
}

const permutate = arr => [...permutations(arr)];

如果唯一需要关注的是全局变量,则可以将其包装在另一个函数中,我的意思是如下所示:

 function permute(_arr) { let ans = []; (function _permute(arr) { let l = arguments[1] || 0, r = arguments[2] || arr.length - 1; if (l == r) { let a = []; a.push(...arr); // To overcome reference problem here. ans.push(a); } else { for (let i = l; i <= r; i++) { [arr[l], arr[i]] = [arr[i], arr[l]]; // Swap with help of new destructuring _permute(arr, l + 1, r); [arr[l], arr[i]] = [arr[i], arr[l]]; // Swap with help of new destructuring } } })(_arr); return ans; } console.log(permute([1, 2, 3, 4])); console.log(permute([1, 2, 3])); console.log(permute([1, 2, 3, 4, 5])); 

您也可以尝试将Array.map与递归结合使用,如下所示,以实现置换。 我还使用了Array.flat (到目前为止,Edge不支持,如果要支持Edge浏览器,则需要polyfill)

 function getForwardArr(arr, i) { return [...arr.slice(i+1), ...arr.slice(0, i)] } function permute(arr) { if (arr.length == 2) return [[...arr], arr.reverse()] else return arr.map((d, i) => permute(getForwardArr(arr, i)).map(v => [d, v].flat())).flat() } console.log(permute([1,2])) console.log(permute([1,2,3])) console.log(permute([1,2,3,4])) 

执行此操作的另一种方法是不传递任何信息,而是重用较小的子问题的结果来构建排列数组并返回该数组。

因此,例如,要构建所有3个元素置换,可以将每个元素放在第一位,并将其与其余元素的所有2个元素置换连接起来(您可以通过递归调用获得):

 function permutations(arr) { if (arr.length <= 1) return [arr]; var res = []; arr.forEach((e, i) => { var smaller = permutations([...arr.slice(0, i), ...arr.slice(i + 1)]); smaller.forEach(p => res.push([e].concat(p))) }); return res; } console.log(permutations([1])); console.log(permutations([1, 2, 3])); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM