千万里不及你
这是一个在没有循环的 JavaScript 中进行排列的函数。像这样使用它:let stra = [..."string"].sort(); // first sort your items in an arraywhile(nextPermutation(stra)) console.log(stra); // keep going until falsefunction nextPermutation(array, first = 0, last = array.length-1) { if(first>=last){ return false; } let i = last; function reverse(i, j){ if(i>=j) return; [array[j], array[i]] = [array[i], array[j]]; reverse(++i, --j); } return (function _(){ const i1 = i; if(array[--i]<array[i1]){ let i2 = last+1; (function decrement(){ if(array[i] >= array[--i2]) decrement(); })(); [array[i], array[i2]] = [array[i2], array[i]]; reverse(i1, last); return true; } if(i===first){ reverse(first, last); return false; } return _(); })();}
慕田峪7331174
这个版本使用了一个相当简单的递归:const without = (n) => (xs) => [... xs .slice (0, n), ... xs .slice (n + 1)]const permutations = (xs) => xs .length == 0 ? [] : xs .length == 1 ? [[xs[0]]] : // else xs .flatMap ((x, i) => permutations (without (i) (xs)) .map (p => [x, ...p]))const stringPermutations = (s) => { return permutations (s .split ('')) .map (ss => ss .join (''))}console .log ( stringPermutations ('abcd')).as-console-wrapper {min-height: 100% !important; top: 0}有一个辅助函数 ,without它返回没有给定索引的数组副本。例如,without (2) (['a', 'b', 'c', 'd', 'e', 'f'])产量['a', 'b', 'd', 'e', 'f']。这仅在我们的 main 函数中使用一次,并且可以轻松内联,但我发现按原样阅读更容易。stringPermutations只需将字符串更改为单字符字符串数组,调用permutations然后将结果数组连接回字符串。重要的部分是permutations。它有两种基本情况:当输入数组为空时,它返回一个空数组。当它只有一个值时,它返回一个数组,其中包含一个包含该值的数组。在所有其他情况下,它依次为第一个元素选择每个元素,将其从列表中删除,并permutations使用剩余列表递归调用后续位置。