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

以一个整数数组作为参数(例如[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中做到这一点


当前回答

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

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

其他回答

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

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])));

我改进了SiGanteng的答案。

现在可以多次调用permute,因为permArr和usedChars每次都被清除。

function permute(input) {
    var permArr = [],
        usedChars = [];
    return (function main() {
        for (var i = 0; i < input.length; i++) {
            var ch = input.splice(i, 1)[0];
            usedChars.push(ch);
            if (input.length == 0) {
                permArr.push(usedChars.slice());
            }
            main();
            input.splice(i, 0, ch);
            usedChars.pop();
        }
        return permArr;
    })();
}

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

在精神上类似于@crl的haskell风格的解决方案,但使用reduce:

function permutations( base ) {
  if (base.length == 0) return [[]]
  return permutations( base.slice(1) ).reduce( function(acc,perm) {
    return acc.concat( base.map( function(e,pos) {
      var new_perm = perm.slice()
      new_perm.splice(pos,0,base[0])
      return new_perm
    }))
  },[])    
}

这是一个非常简洁的递归解决方案,允许您输入输出排列的大小,类似于统计运算符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]]

目前最快、最有效、最优雅的版本(2020年)

function getArrayMutations (arr, perms = [], len = arr.length) { if (len === 1) perms.push(arr.slice(0)) for (let i = 0; i < len; i++) { getArrayMutations(arr, perms, len - 1) len % 2 // parity dependent adjacent elements swap ? [arr[0], arr[len - 1]] = [arr[len - 1], arr[0]] : [arr[i], arr[len - 1]] = [arr[len - 1], arr[i]] } return perms } const arrayToMutate = [1, 2, 3, 4, 5, 6, 7, 8, 9] const startTime = performance.now() const arrayOfMutations = getArrayMutations(arrayToMutate) const stopTime = performance.now() const duration = (stopTime - startTime) / 1000 console.log(`${arrayOfMutations.length.toLocaleString('en-US')} permutations found in ${duration.toLocaleString('en-US')}s`)