2

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!

8
  • 1
    I think it's wise to avoid expanding the stack with each call of the function fac. It can lead to stackoverflow (no pun intended). Commented Apr 2, 2020 at 5:43
  • recursive programming is okay, but i think a solution using a while or a for loop would be better Commented Apr 2, 2020 at 5:44
  • 3
    Recursion is okay, but recursing with an ever-increasing stack isn't. Commented Apr 2, 2020 at 5:46
  • You can look at the permutation function in Javascript Permutations magic trick and replace the for loop with forEach over the array of characters. Commented Apr 2, 2020 at 7:01
  • 2
    @Foxeye.Rinx—the OP says "suppose that none of the character is repeated". Commented Apr 2, 2020 at 13:13

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

couldn't let this answer go without up-votes... beautiful work, Scott
Thank, umm @Thankyou. Good to see you back around these parts. I was quite surprised not to easily find a recursive JS permutations answer already. But I didn't look too hard.
1

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 _();
  })();
}

2 Comments

Which line has the for loop ? As for the while loop, that is only in the example usage of the nextPermutation function. There is no loop in the nextPermutation function by the way.
Must have been dreaming… :-(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.