์์ด, ์กฐํฉ ์๊ณ ๋ฆฌ์ฆ์ ์ฝ๋ฉํ ์คํธ์์ ๋น๋ฒํ๊ฒ ์ถ์ ๋๋ค. ๊ทธ๋ผ์๋ ํญ์ ๋ง์ฃผ์น๋ฉด ๊ตฌ๊ธ๋ง์ํ๋ค..
๋ฐ๋ผ์ ์ค๋ ์์ด, ์กฐํฉ ์๋ฒฝํ๊ฒ ์ดํดํ๊ณ ๋๋ด๋ณด๋ ค๊ณ ํ๋ค.
์กฐํฉ ์ฌ๊ท ๊ตฌํ
์กฐํฉ์ ์๋์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
๋ฐฐ์ด [1, 2, 3, 4] ์์ 3๊ฐ๋ฅผ ์ ํํ๋ ์กฐํฉ์ ๊ตฌํ ๋
1์ ๊ณ ์ -> ๋๋จธ์ง [2, 3, 4] ์ค์์ 2๊ฐ์ฉ ์กฐํฉ์ ๊ตฌํ๋ค. -> [1(๊ณ ์ ) + ๊ฐ๊ฐ ๋ฝ์๊ฑฐ]
2๋ฅผ ๊ณ ์ -> ๋๋จธ์ง [3, 4] ์ค์์ 2๊ฐ์ฉ ์กฐํฉ์ ๊ตฌํ๋ค. -> [2(๊ณ ์ ) + ๊ฐ๊ฐ ๋ฝ์๊ฑฐ]
3์ ๊ณ ์ -> ๋๋จธ์ง [4] ์ค์์ 2๊ฐ์ฉ ์กฐํฉ์ ๊ตฌํ๋ค.
4๋ฅผ ๊ณ ์ -> ๋๋จธ์ง [] ์์ 2๊ฐ์ฉ ์กฐํฉ์ ๊ตฌํ๋ค.
์ฌ๊ธฐ์ ๋๋จธ์ง ๋ฐฐ์ด์ ๋ํด ์กฐํฉ์ ๊ตฌํ ๋๋, ์ฌ๊ทํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
- ๊ธฐ์ ์กฐ๊ฑด : 1๊ฐ๋ฅผ ๋ฝ์๋, ๋ชจ๋ ๋ฐฐ์ด์ ์์๋ฅผ ํ๋์ฉ ์ ํํด ๋ฐฐ์ด๋ก ๋ฆฌํดํ๋ค.
- forEach๋ฌธ์ ์ด์ฉํด, ๋ฐฐ์ด์ ๋ชจ๋ ์์๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ํ๋ฒ์ฉ ๊ณ ์ ๋๊ฒ ํ๋ค.
- ๊ณ ์ ๋ ๊ฐ์ ์ ์ํ ๋๋จธ์ง ๋ค ๋ฐฐ์ด์ ๋ํด ์กฐํฉ์ ๊ตฌํ๋ค. ์ด๋, ์ ํํ๋ ๊ฐ์๋ฅผ ํ๋์ฉ ์ค์ฌ๊ฐ๋ค.
- ์ด๋ ๊ฒ ์กฐํฉ์ ๋ง๋ค์ด์จ ๊ฒฐ๊ณผ์ ๊ณ ์ ๋ ๊ฐ์ ๋ถ์ด๊ณ , ์ ๊ฐ ๊ตฌ๋ฌธ(...)์ ์ด์ฉํด ๋ฆฌํดํ ๋ฐฐ์ด์ ๋ฃ๋๋ค.
- ๋ฐฐ์ด๋ณด๋ค ๋ฝ๋ ๊ฐ์๊ฐ ๋ ๋ง์ ๊ฒฝ์ฐ ๋น ๋ฐฐ์ด์ด ๋ฆฌํด๋๊ธฐ ๋๋ฌธ์, ์ต์ข ๊ฒฐ๊ณผ๊ฐ์ ํฌํจ๋์ง ์๋๋ค.
let arr = [1, 2, 3, 4]
function getCombinations(arr, selectNumber) {
const results = [];
if (selectNumber === 1) return arr.map((item) => item);
arr.forEach((fixed, index, origin) => {
const rest = origin.slice(index + 1); //๊ณ ์ ์ ์ ์ธํ ๋๋จธ์ง.
const combinations = getCombinations(rest, selectNumber - 1); //๋๋จธ์ง์ ๋ํ ์กฐํฉ ๊ตฌํ๊ธฐ.
const attached = combinations.map((combination) => [fixed, ...combination]); //๊ณ ์ ๊ฐ + ๋ง๋ค์ด์ง ์กฐํฉ.
results.push(...attached);
});
return results;
}
console.log(getCombinations(arr, 3)); //[ [ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 3, 4 ], [ 2, 3, 4 ] ]
1, 2, 3 ์ค์ 2๊ฐ๋ฅผ ๋ฝ๋ ์กฐํฉ๊ณผ์ ์ ์์ฑํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค. (์๋์ฝ๋๋ผ ์ฝ๊ธฐ ํ๋ค์๋์๋ค..)
์์ด ์ฌ๊ท ๊ตฌํ
์์ด์ ์์๋ฅผ ๊ณ ๋ คํ ๋ฝ๊ธฐ์ด๋ค.
์์ด nPr = ์กฐํฉ nCr * r!
์กฐํฉ์ ์์๋ฅผ ๋ถ์ฌํ๋ฉด ์์ด์ด ๋๋ค.
์กฐํฉ ์ฝ๋์์ ๋๋จธ์ง ๋ฐฐ์ด์ ๊ตฌํ๋ ์ฝ๋๋ง ๋ฐ๊พธ๋ฉด, ํด๊ฒฐํ ์ ์๋ค.
const rest = origin.slice(index + 1); //์กฐํฉ์ ๊ตฌํ ๋ ๋๋จธ์ง ๋ณ์
const rest = [...origin.slice(0, index), ...origin.slice(index + 1)]; //์์ด์ ๊ตฌํ ๋ ๋๋จธ์ง ๋ณ์
์กฐํฉ์ rest๋ ํด๋น ๊ณ ์ ๊ฐ์ ์ ์ธํ ๋๋จธ์ง ๋ค์ ๋ถ๋ถ์ด์ง๋ง,
์์ด์ rest๋ ํด๋น ๊ณ ์ ๊ฐ์ ์ ์ธํ ๋๋จธ์ง ๋ฐฐ์ด์ rest๋ก ๋จ๊ธฐ๋ ์ฝ๋๋ค.
์ ์ฒด ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
let arr = [1, 2, 3]
function getPermutations(arr, selectNumber) {
const results = [];
if (selectNumber === 1) return arr.map((item) => [item]);
arr.forEach((fixed, index, origin) => {
const rest = [...origin.slice(0, index), ...origin.slice(index + 1)]; //๊ณ ์ ์ ์ ์ธํ ๋๋จธ์ง.
const permutations = getPermutations(rest, selectNumber - 1); //๋๋จธ์ง ๋ฐฐ์ด์ ๋ํด ์์ด์ ๊ตฌํ๋ค.
const attached = permutations.map((permutation) => [fixed, ...permutation]); //๊ณ ์ ๊ฐ + ๋ง๋ค์ด์ง ์์ด.
results.push(...attached);
});
return results;
}
console.log(getPermutations(arr, 2)); //[ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ]
๋ค์์ ๋ด๊ฐ ์ดํดํ๋ ค๊ณ ์ด [1, 2, 3] ์ค์์ 2๊ฐ๋ฅผ ์ ํํ ๋์ ์์ด ์๋์ฝ๋์ด๋ค.
์์ด ๋ฐ๋ณต๋ฌธ ๊ตฌํ
for๋ฐ๋ณต๋ฌธ์ r๋ฒ ์ค์ฒฉํ๋ฉด ๋๋ค. ์ด ๋, ๋ฐ๋ณต๋ฌธ์ ์ํด ์ ํ๋ i, j, k๋ ๋ชจ๋ ๋ค๋ฅธ ๊ฐ์ ๊ฐ๋ฅดํค๋๋ก ๊ฐ์ ํด์ผํ๋ค.
const arr = [1, 2, 3, 4];
const ans = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
for (let k = 0; k < arr.length; k++) {
if (arr[i] === arr[j] || arr[i] === arr[k] || arr[j] === arr[k]) {
continue;
}
const current = [arr[i], arr[j], arr[k]];
ans.push(current);
}
}
}
console.log(ans);
n๊ฐ์ค r๊ฐ๋ฅผ ๋ฝ์ ๋์ดํ๋ ์์ด์๊ณ ๋ฆฌ์ฆ์ ์ง๋ ค๋ฉด, r๊ฐ์ ์ค์ฒฉ for๋ฌธ์ด ํ์ํ๋ค.
์ฐธ๊ณ ์๋ฃ
- https://pul8219.github.io/algorithm/algorithm-permutation-and-combination/
- https://jun-choi-4928.medium.com/javascript%EB%A1%9C-%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-21df4b536349
'๐คฏ ๋ฐ์ดํฐ๊ตฌ์กฐ์ ์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ] ์ด์งํ์ ์ ๋ฆฌ (0) | 2023.05.16 |
---|---|
[์๊ณ ๋ฆฌ์ฆ] ์ฌ๊ทํจ์๋ฅผ ์ด์ฉํ DFS(2) (0) | 2022.12.01 |
[์๊ณ ๋ฆฌ์ฆ] ์ธ์ ํ๋ ฌ์ ํตํ ์ธ์ ๋ฆฌ์คํธ ๊ตฌํ, DFS(1) (0) | 2022.11.26 |
[์๊ณ ๋ฆฌ์ฆ] ์ฝ์ ์ ๋ ฌ ๊ตฌํ (c์ธ์ด) (0) | 2022.11.12 |
[์๊ณ ๋ฆฌ์ฆ] ๋ฒ๋ธ ์ ๋ ฌ ๊ตฌํ (c์ธ์ด) (0) | 2022.11.10 |