mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 07:01:18 +08:00
Add permutations and combinations.
This commit is contained in:
parent
e8de00c969
commit
4434e96413
18
src/algorithms/string/combinations/README.md
Normal file
18
src/algorithms/string/combinations/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Combinations
|
||||
|
||||
When the order doesn't matter, it is a **Combination**.
|
||||
|
||||
When the order **does** matter it is a **Permutation**.
|
||||
|
||||
**"My fruit salad is a combination of apples, grapes and bananas"**
|
||||
We don't care what order the fruits are in, they could also be
|
||||
"bananas, grapes and apples" or "grapes, apples and bananas",
|
||||
its the same fruit salad.
|
||||
|
||||
## Combinations without repetitions
|
||||
|
||||
## Combinations with repetitions
|
||||
|
||||
## References
|
||||
|
||||
[Math Is Fun](https://www.mathsisfun.com/combinatorics/combinations-permutations.html)
|
@ -0,0 +1,53 @@
|
||||
import permutateWithRepetition from '../permutateWithRepetitions';
|
||||
|
||||
describe('permutateWithRepetition', () => {
|
||||
it('should permutate string with repetition', () => {
|
||||
const permutations0 = permutateWithRepetition('');
|
||||
expect(permutations0).toEqual([]);
|
||||
|
||||
const permutations1 = permutateWithRepetition('A');
|
||||
expect(permutations1).toEqual(['A']);
|
||||
|
||||
const permutations2 = permutateWithRepetition('AB');
|
||||
expect(permutations2).toEqual([
|
||||
'AA',
|
||||
'AB',
|
||||
'BA',
|
||||
'BB',
|
||||
]);
|
||||
|
||||
const permutations3 = permutateWithRepetition('ABC');
|
||||
expect(permutations3).toEqual([
|
||||
'AAA',
|
||||
'AAB',
|
||||
'AAC',
|
||||
'ABA',
|
||||
'ABB',
|
||||
'ABC',
|
||||
'ACA',
|
||||
'ACB',
|
||||
'ACC',
|
||||
'BAA',
|
||||
'BAB',
|
||||
'BAC',
|
||||
'BBA',
|
||||
'BBB',
|
||||
'BBC',
|
||||
'BCA',
|
||||
'BCB',
|
||||
'BCC',
|
||||
'CAA',
|
||||
'CAB',
|
||||
'CAC',
|
||||
'CBA',
|
||||
'CBB',
|
||||
'CBC',
|
||||
'CCA',
|
||||
'CCB',
|
||||
'CCC',
|
||||
]);
|
||||
|
||||
const permutations4 = permutateWithRepetition('ABCD');
|
||||
expect(permutations4.length).toBe(4 * 4 * 4 * 4);
|
||||
});
|
||||
});
|
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @param {string} str
|
||||
* @return {string[]}
|
||||
*/
|
||||
export default function permutateWithRepetition(str) {
|
||||
// There is no permutations for empty string.
|
||||
if (!str || str.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// There is only one permutation for the 1-character string.
|
||||
if (str.length === 1) {
|
||||
return [str];
|
||||
}
|
||||
|
||||
// Let's create initial set of permutations.
|
||||
let previousPermutations = Array.from(str);
|
||||
let currentPermutations = [];
|
||||
let permutationSize = 1;
|
||||
|
||||
// While the size of each permutation is less then or equal to string length...
|
||||
while (permutationSize < str.length) {
|
||||
// Reset all current permutations.
|
||||
currentPermutations = [];
|
||||
|
||||
for (let pemIndex = 0; pemIndex < previousPermutations.length; pemIndex += 1) {
|
||||
for (let charIndex = 0; charIndex < str.length; charIndex += 1) {
|
||||
const currentPermutation = previousPermutations[pemIndex] + str[charIndex];
|
||||
currentPermutations.push(currentPermutation);
|
||||
}
|
||||
}
|
||||
|
||||
// Make current permutations to be the previous ones.
|
||||
previousPermutations = currentPermutations.slice(0);
|
||||
|
||||
// Increase permutation size counter.
|
||||
permutationSize += 1;
|
||||
}
|
||||
|
||||
return currentPermutations;
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
/**
|
||||
* @param {string} str
|
||||
* @return {string[]}
|
||||
*/
|
||||
export default function permutateWithoutRepetitions(str) {
|
||||
if (str.length === 0) {
|
||||
return [];
|
||||
|
Loading…
Reference in New Issue
Block a user