问题
I'm trying to write a function in Javascript that can return the number of permutations, and also show all the permutations of a string (suppose that non of the character is repeated) using recursive methods. I've seen a lot using for
loop, but is there a way that I can obtain the same outcome without using it?
For the number of permutations, here is my attempt without using for
loop
var permutation = function (s) {
var fac = function (t) {
if (t === 0) return 1;
return t*fac(t-1);
};
return fac(s.length);
};
It works well, but I don't know how to continue with the list of permutations. Thanks for the help!
回答1:
This version uses a fairly simple recursion:
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}
There is a helper function, without
, which returns a copy of an array without the given index. For instance, without (2) (['a', 'b', 'c', 'd', 'e', 'f'])
yields ['a', 'b', 'd', 'e', 'f']
. This is only used once inside our main function and could be easily inlined, but I find it easier to read as is.
stringPermutations
merely changes the string into an array of single-character strings, calls permutations
and then joins the resulting arrays back into strings.
The important part is permutations
. It has two base cases: when the input array is empty, it returns an empty array. When it has only a single value, it returns an array containing an array containing that value. In all other cases, it selects each element in turn for the first element, removing it from the list and recursively calling permutations
with the remaining list for the subsequent positions.
回答2:
Here's a function to do permutations in JavaScript without loops.
Use it like so:
let stra = [..."string"].sort(); // first sort your items in an array
while(nextPermutation(stra)) console.log(stra); // keep going until false
function 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 _();
})();
}
来源:https://stackoverflow.com/questions/60984874/permutations-in-javascript