diff --git a/src/algorithms/string/permutations/README.md b/src/algorithms/string/permutations/README.md new file mode 100644 index 00000000..64b7f0bd --- /dev/null +++ b/src/algorithms/string/permutations/README.md @@ -0,0 +1,9 @@ +# String Permutations + +A permutation, also called an “arrangement number” or “order”, is a rearrangement of +the elements of an ordered list `S` into a one-to-one correspondence with `S` itself. +A string of length `n` has `n!` permutation. + +Below are the permutations of string `ABC`. + +`ABC ACB BAC BCA CBA CAB` diff --git a/src/algorithms/string/permutations/__test__/permutateString.test.js b/src/algorithms/string/permutations/__test__/permutateString.test.js new file mode 100644 index 00000000..c252516f --- /dev/null +++ b/src/algorithms/string/permutations/__test__/permutateString.test.js @@ -0,0 +1,68 @@ +import permutateString from '../permutateString'; + +describe('permutateString', () => { + it('should permutate string', () => { + const permutations0 = permutateString(''); + expect(permutations0).toEqual([]); + + const permutations1 = permutateString('A'); + expect(permutations1).toEqual(['A']); + + const permutations2 = permutateString('AB'); + expect(permutations2.length).toBe(2); + expect(permutations2).toEqual([ + 'BA', + 'AB', + ]); + + const permutations6 = permutateString('AA'); + expect(permutations6.length).toBe(2); + expect(permutations6).toEqual([ + 'AA', + 'AA', + ]); + + const permutations3 = permutateString('ABC'); + expect(permutations3.length).toBe(2 * 3); + expect(permutations3).toEqual([ + 'CBA', + 'BCA', + 'BAC', + 'CAB', + 'ACB', + 'ABC', + ]); + + const permutations4 = permutateString('ABCD'); + expect(permutations4.length).toBe(2 * 3 * 4); + expect(permutations4).toEqual([ + 'DCBA', + 'CDBA', + 'CBDA', + 'CBAD', + 'DBCA', + 'BDCA', + 'BCDA', + 'BCAD', + 'DBAC', + 'BDAC', + 'BADC', + 'BACD', + 'DCAB', + 'CDAB', + 'CADB', + 'CABD', + 'DACB', + 'ADCB', + 'ACDB', + 'ACBD', + 'DABC', + 'ADBC', + 'ABDC', + 'ABCD', + ]); + + const permutations5 = permutateString('ABCDEF'); + expect(permutations5.length).toBe(2 * 3 * 4 * 5 * 6); + }); +}); diff --git a/src/algorithms/string/permutations/permutateString.js b/src/algorithms/string/permutations/permutateString.js new file mode 100644 index 00000000..49d2f307 --- /dev/null +++ b/src/algorithms/string/permutations/permutateString.js @@ -0,0 +1,35 @@ +export default function permutateString(str) { + if (str.length === 0) { + return []; + } + + if (str.length === 1) { + return [str]; + } + + const permutations = []; + + // Get all permutations of string of length (n - 1). + const previousString = str.substring(0, str.length - 1); + const previousPermutations = permutateString(previousString); + + // Insert last character into every possible position of every previous permutation. + const lastCharacter = str.substring(str.length - 1); + + for ( + let permutationIndex = 0; + permutationIndex < previousPermutations.length; + permutationIndex += 1 + ) { + const currentPermutation = previousPermutations[permutationIndex]; + + // Insert strLastCharacter into every possible position of currentPermutation. + for (let positionIndex = 0; positionIndex <= currentPermutation.length; positionIndex += 1) { + const permutationPrefix = currentPermutation.substr(0, positionIndex); + const permutationSuffix = currentPermutation.substr(positionIndex); + permutations.push(permutationPrefix + lastCharacter + permutationSuffix); + } + } + + return permutations; +}