我试图写一个函数,它做以下工作:

以一个整数数组作为参数(例如[1,2,3,4]) 创建一个包含[1,2,3,4]的所有可能排列的数组,每个排列的长度为4

下面的函数(我在网上找到的)通过接受一个字符串作为参数,并返回该字符串的所有排列来实现这一点

我不知道如何修改它,使它与整数数组一起工作,(我认为这与一些方法在字符串上的工作方式不同于在整数上的工作方式有关,但我不确定…)

let permArr = [];
let usedChars = [];

function permute(input) {
    const chars = input.split("");
    for (let i = 0; i < chars.length; i++) {
        const ch = chars.splice(i, 1);
        usedChars.push(ch);
        if (chars.length === 0) {
            permArr[permArr.length] = usedChars.join("");
        }
        permute(chars.join(""));
        chars.splice(i, 0, ch);
        usedChars.pop();
    }
    return permArr
};

注意:我希望函数返回整数数组,而不是字符串数组。

我真的需要解决方案是在JavaScript。我已经知道如何在python中做到这一点


当前回答

有点晚了,但喜欢在这里添加一个稍微优雅的版本。可以是任何数组…

function permutator(inputArr) {
  var results = [];

  function permute(arr, memo) {
    var cur, memo = memo || [];

    for (var i = 0; i < arr.length; i++) {
      cur = arr.splice(i, 1);
      if (arr.length === 0) {
        results.push(memo.concat(cur));
      }
      permute(arr.slice(), memo.concat(cur));
      arr.splice(i, 0, cur[0]);
    }

    return results;
  }

  return permute(inputArr);
}

添加ES6(2015)版本。也不会改变原始输入数组。工作在控制台Chrome…

const permutator = (inputArr) => {
  let result = [];

  const permute = (arr, m = []) => {
    if (arr.length === 0) {
      result.push(m)
    } else {
      for (let i = 0; i < arr.length; i++) {
        let curr = arr.slice();
        let next = curr.splice(i, 1);
        permute(curr.slice(), m.concat(next))
     }
   }
 }

 permute(inputArr)

 return result;
}

所以…

permutator(['c','a','t']);

收益率…

[ [ 'c', 'a', 't' ],
  [ 'c', 't', 'a' ],
  [ 'a', 'c', 't' ],
  [ 'a', 't', 'c' ],
  [ 't', 'c', 'a' ],
  [ 't', 'a', 'c' ] ]

和…

permutator([1,2,3]);

收益率…

[ [ 1, 2, 3 ],
  [ 1, 3, 2 ],
  [ 2, 1, 3 ],
  [ 2, 3, 1 ],
  [ 3, 1, 2 ],
  [ 3, 2, 1 ] ]

其他回答

我尝试着做一个简洁而可读的版本,并且是纯函数式编程。

function stringPermutations ([...input]) {
  if (input.length === 1) return input;

  return input
    .map((thisChar, index) => {
      const remainingChars = [...input.slice(0, index), ...input.slice(index + 1)];
      return stringPermutations(remainingChars)
        .map(remainder => thisChar + remainder);
    })
    .reduce((acc, cur) => [...acc, ...cur]);
}

注意,参数格式化将输入字符串转换为数组。不知道这是不是有点太神奇了。我不确定在野外见过。为了真正的可读性,我可能会用input =[…]输入]作为函数的第一行。

这里有一个很酷的解决方案

Const旋转= ([l,…]Ls], right=[]) => L !== void 0 ?[[l,…ls,……右),…旋转(ls,[…对,l])]: [] Const排列= ([x,…xs]) => X !== 0 ?排列(x) .flatMap ((p) = >旋转(p (x)…… ])) : [[]] console.log(排列(“猫”)

无需外部数组或附加函数即可回答

function permutator (arr) {
  var permutations = [];
  if (arr.length === 1) {
    return [ arr ];
  }

  for (var i = 0; i <  arr.length; i++) { 
    var subPerms = permutator(arr.slice(0, i).concat(arr.slice(i + 1)));
    for (var j = 0; j < subPerms.length; j++) {
      subPerms[j].unshift(arr[i]);
      permutations.push(subPerms[j]);
    }
  }
  return permutations;
}

如果您注意到,代码实际上在进行任何排列之前将字符拆分为一个数组,因此只需删除连接和拆分操作

var permArr = [], 使用的字符 = []; 函数排列(输入) { var i, ch; for (i = 0; i < input.length; i++) { ch = input.splice(i, 1)[0]; usedChars.push(ch); if (input.length == 0) { permArr.push(usedChars.slice()); } 排列(输入); input.splice(i, 0, ch); usedChars.pop(); } 返回烫发 }; document.write(JSON.stringify(permute([5, 3, 7, 1])));

这是一个非常简洁的递归解决方案,允许您输入输出排列的大小,类似于统计运算符nPr。“排列”。这允许您获得特定大小的所有可能的排列。

function generatePermutations(list, size=list.length) {
    if (size > list.length) return [];
    else if (size == 1) return list.map(d=>[d]); 
    return list.flatMap(d => generatePermutations(list.filter(a => a !== d), size - 1).map(item => [d, ...item]));
}

generatePermutations ([1, 2, 3])

[[1, 2, 3],[1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

generatePermutations((1、2、3),2)

[[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]