[Algorithm] ์์ด / ์กฐํฉ ๊ฐ๋ ๊ณผ ์๊ณ ๋ฆฌ์ฆ ๊ตฌํ
์์ด Permutation
๊ฐ๋
์์ด์ ์๋ก ๋ค๋ฅธ n๊ฐ ์์ ์ค์์ r๊ฐ๋ฅผ ์ ํํ์ฌ ์์๋๋ก ๋์ดํ๋ ๋ฐฉ๋ฒ์ ์๋ฏธํ๋ค. ์์ด์์ ์์๊ฐ ๊ฒฐ๊ณผ์ ์ํฅ์ ๋ฏธ์น๊ธฐ ๋๋ฌธ์ ์์๊ฐ ์ค์ํ๋ค. ๋์ผํ ์์๋ฅผ ์๋ก ๋ค๋ฅธ ์์๋ก ๋์ดํ๋ฉด, ๊ฐ๊ฐ์ ๋ณ๊ฐ์ ์์ด๋ก ๊ฐ์ฃผํ๋ค. ์๋ฅผ ๋ค์ด A, B, C์์ A, B ๋ ์์๋ฅผ ์ ํํ๋ ๊ฒฝ์ฐ AB์ BA๋ ์๋ก ๋ค๋ฅธ ์์ด์ด๋ค.
- A ์ ํ, ๋จ์ ๊ธ์ B, C
- B ์ ํ, ๋จ์ ๊ธ์ C (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
AB
- C ์ ํ, ๋จ์ ๊ธ์ B (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
AC
- B ์ ํ, ๋จ์ ๊ธ์ C (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
- B ์ ํ, ๋จ์ ๊ธ์ A, C
- A ์ ํ, ๋จ์ ๊ธ์ C (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
BA
- C ์ ํ, ๋จ์ ๊ธ์ A (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
BC
- A ์ ํ, ๋จ์ ๊ธ์ C (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
- C ์ ํ, ๋จ์ ๊ธ์ A, B
- A ์ ํ, ๋จ์ ๊ธ์ B (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
CA
- B ์ ํ, ๋จ์ ๊ธ์ A (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
CB
- A ์ ํ, ๋จ์ ๊ธ์ B (2์๋ฆฌ ์์ด์ด๋ฏ๋ก ๋ฌด์) →
A, B, C 3๊ฐ์ง ๋ฌธ์(n=3
)๋ก ๋ง๋ค ์ ์๋ 2์๋ฆฌ ์์ด(r=2
)์ ์๋ ์ด 6๊ฐ์ง๋ค. ์ฒซ ๋ฒ์งธ ์๋ฆฌ์ ์ฌ ์ ์๋ ๋ฌธ์๋ A, B, C 3๊ฐ์ง๋ฅผ ์ ํํ ์ ์๋ค. ๋ ๋ฒ์งธ ์๋ฆฌ์๋ ๋จ์ ๋ ๋ฌธ์๊ฐ ์์นํ ์ ์์ผ๋ฏ๋ก 2๊ฐ์ง๋ฅผ ์ ํํ ์ ์๋ค. ๋ฐ๋ผ์ ๋ชจ๋ ์์ด์ ์๋ $3 \times 2 = 6$์ด ๋๋ค.
์ด์ฒ๋ผ ์์ด์ ๊ฐ ๋จ๊ณ์์ ์ ํํ ์ ์๋ ๋ชจ๋ ์๋ฅผ ๊ณฑํ ๊ฒ๊ณผ ๊ฐ์ผ๋ฏ๋ก ํฉํ ๋ฆฌ์ผ์ ๊ฐ๋ ์ ๋ถ๋ถ์ ์ผ๋ก ํฌํจํ์ฌ $n \times (n-1) \times (n-2) \times ... \times (n-r+1)$ ์์ผ๋ก ํํํ ์ ์๋ค. ๋ง์ง๋ง ์ ํ์ $n-r+1$๋ก ํํํ ์ด์ ๋ r๋ฒ์งธ ์์๋ฅผ ์ ํํ ์์ ์ r-1๊ฐ์ ์์๋ฅผ ์ ํํ ์ํ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ฅผ๋ค์ด n=5, r=3์ผ ๋ r(3)๋ฒ์งธ ์์๋ฅผ ์ ํํ ์ฐจ๋ก์์ ์ด๋ฏธ r-1(2)๊ฐ์ ์์๋ฅผ ์ ํํ ์ํ์ด๋ค. ๋ฐ๋ผ์ ๋ง์ง๋ง ์ ํ(r๋ฒ์งธ)์ ๋จ์ ์์์ ์๋ n(5)์์ r-1(2)๋ฅผ ๋บ 3์ด ๋๋ค. ์ด๋ฅผ ์์ผ๋ก ํํํ๋ฉด $n-(r-1)$์ด ๋๊ณ ๋ถ๋ฐฐ ๋ฒ์น์ผ๋ก ๋จ์ํํ๋ฉด $n-r+1$์ด ๋๋ ๊ฒ.
์์ด์ ์ํ์ ๊ณต์์ผ๋ก ํ๊ธฐํ๋ฉด $P(n,r)=\frac{n!}{(n-r)!}$ ์ด ๋๋ค. $\frac{n!}{(n-r)!}$ ์์ ๊ณ์ฐํด๋ณด๋ฉด $(n-r)!$์ ํด๋นํ๋ ํญ์ ์ฝ๋ถ๋ ํ ์ง์์ ธ์ $n \times (n-1) \times (n-2) \times ... \times (n-r+1)$ ํํ๊ฐ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
$$P(3, 2) = \frac{3!}{(3-2)!} = \frac{3 \cdot 2 \cdot \cancel{1}}{\cancel{1}} = 3 \cdot 2 = 6$$
$$P(5, 3) = \frac{5!}{(5-3)!} = \frac{5 \cdot 4 \cdot 3 \cdot \cancel{2 \cdot 1}}{\cancel{2 \cdot 1}} = 5 \cdot 4 \cdot 3 = 60$$
๐ก ์ฝ๋ถ์ ๋ถ์/๋ถ๋ชจ๊ฐ ๊ณตํต๋ ์ธ์๋ฅผ ๊ฐ์ง ๋, ์ด ์ธ์๋ก ๋ถ์์ ๋ถ๋ชจ๋ฅผ ๋๋ ์ ๋ถ์๋ฅผ ๋ ๊ฐ๋จํ ํํ๋ก ๋ง๋๋ ๊ณผ์ . โ ๋ถ์/๋ถ๋ชจ์ ์ต๋๊ณต์ฝ์(GCD)๋ฅผ ์ฐพ๊ณ , โก๋ถ์/๋ถ๋ชจ๋ฅผ ์ต๋๊ณต์ฝ์๋ก ๋๋ ํ, โข๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์๋ก์ด ๋ถ์/๋ถ๋ชจ์ ์ฌ์ฉํ์ฌ ๋ถ์๋ฅผ ๊ฐ์ํํ๋ค. ๋คํญ์์ผ๋ก ๋ ๋ถ์๋ ๋ถ๋ชจ์ ๋ถ์๋ฅผ ์ธ์๋ถํด(์ฃผ์ด์ง ์ ์๋ฅผ ๋ ์ด์ ๋๋ ์ ์๋ ์์๋ค์ ๊ณฑ์ผ๋ก ํํ)ํ์ฌ ๋คํญ์(1๊ฐ ์ด์์ ํญ, e.g. 2x + 4
๋ ํญ 2๊ฐ)์ ๊ณฑ์ผ๋ก ๋ํ๋ธ ๋ค ๋ถ์/๋ถ๋ชจ์ ๋ชจ๋ ์กด์ฌํ๋ ๋คํญ์์ ์ฝ๋ถํด์ ์์ค๋ค.
๐ก ์์ด์ $P(n,r)$ ํน์ $_nP_r$๋ก ํ๊ธฐํ ์ ์๋ค. P๋ ์๋จ์ด Permutation์ ์ฒซ ๊ธ์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
์ค์ํ ์์
- ์ํธ ์์ฑ : 0~9๊น์ง ์ซ์๋ก 4์๋ฆฌ ์ํธ๋ฅผ ์ค์ ํ ๋, ๊ฐ ์๋ฆฌ์ ๋ค์ด๊ฐ๋ ์ซ์์ ์์์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ค. ์๋ฅผ๋ค์ด [1, 2, 3, 4]์ [4, 3, 2, 1]์ ์๋ก ๋ค๋ฅธ ์ํธ๋ค.
- ์์ ๊ฒฐ์ : ์คํฌ์ธ ๋ํ์์ A, B, C ์ ์๊ฐ ๊ฐ๊ฐ 1๋ฑ~3๋ฑ์ ์ฐจ์งํ๋ ๊ฒ๊ณผ C, B, A๊ฐ 1๋ฑ~3๋ฑ์ ์ฐจ์งํ๋ ๊ฒ์ ์ ํ ๋ค๋ฅด๋ค. ์ฆ, ๊ฒฐ์น์ ์ ๋จผ์ ๋ค์ด์จ ์์์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๋ ๋ฌ๋ผ์ง๋ค.
๊ตฌํ
const getPermutations = (arr, permSize = arr.length, curPerm = []) => {
// ํ์ฌ ์์ด ๊ธธ์ด๊ฐ ์๊ตฌํ๋ ์์ด ํฌ๊ธฐ์ ๊ฐ์ผ๋ฉด ํ์ฌ ์์ด ๋ฐํ (Base Case)
if (curPerm.length === permSize) return [curPerm];
// ๋ฐฐ์ด์ด ๋น์ด์๊ฑฐ๋ ์๊ตฌํ๋ ์์ด ํฌ๊ธฐ๊ฐ 0์ด๋ฉด ๋น ๋ฐฐ์ด ๋ฐํ
if (arr.length === 0 || permSize === 0) return [];
return arr.reduce((allPerms, item, i) => {
const restItems = arr.slice(0, i).concat(arr.slice(i + 1));
const nextPerm = curPerm.concat(item);
return allPerms.concat(getPermutations(restItems, permSize, nextPerm));
}, []);
};
getPermutations(['A', 'B', 'C'], 2); // [['A', 'B'], ['A', 'C'], ...]
- ์
๋ ฅ๋ฐ์ ๋ฐฐ์ด์ ์์๋ฅผ ํ๋์ฉ ์ ํํ์ฌ
curPerm
์์ด ๋ฐฐ์ด์ ์ถ๊ฐํ๋ค - ์ ํํ ์์๋ฅผ ์ ์ธํ ๋๋จธ์ง ์์๋ฅผ
restItems
๋ฐฐ์ด(๋ค์ ์์ด ์์ฑ ๋จ๊ณ์์ ์ฌ์ฉ)์ ์ ์ฅํ๋ค - ๋๋จธ์ง ์์์ ์์ด ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ์ฌ๊ท์ ์ผ๋ก(1~2 ๊ณผ์ ๋ฐ๋ณต) ์์ด์ ์์ฑํ๋ค
- ์ฌ๊ท ๊ณผ์ ์ ํตํด ์์ฑ๋ ๋ชจ๋ ์์ด์ ํ๋์ ๋ฐฐ์ด๋ก ๋ง๋ ํ ๋ฐํํ๋ค
์กฐํฉ Combination
๊ฐ๋
์กฐํฉ์ ์๋ก ๋ค๋ฅธ n๊ฐ ์์ ์ค์์ ์์์ ์๊ด์์ด r๊ฐ๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์ ์๋ฏธํ๋ค. ์กฐํฉ์์ ์ ํํ ์์๋ค์ ์์๋ฅผ ๊ณ ๋ คํ์ง ์๋๋ค. ์๋ฅผ ๋ค์ด A, B, C์์ A, B ๋ ์์๋ฅผ ์ ํํ๋ ๊ฒฝ์ฐ AB์ BA๋ ๋์ผํ ์กฐํฉ์ผ๋ก ๊ฐ์ฃผํ๋ค. ์กฐํฉ์์ ์ค๋ณต์ ํผํ๊ธฐ ์ํด ๊ฐ ๋จ๊ณ์์ ์ ํํ ์์ ๋ค์ ์๋ ์์๋ค๋ง ์กฐํฉ์ ๋์์ผ๋ก ๊ณ ๋ คํ๋ค.
- A ์ ํ, ๋จ์ ๊ธ์ B, C
- B ์ ํ, ๋จ์ ๊ธ์ C (2์๋ฆฌ ์กฐํฉ์ด๋ฏ๋ก ๋ฌด์) →
AB
- C ์ ํ, ๋จ์ ๊ธ์ ็ก →
AC
- B ์ ํ, ๋จ์ ๊ธ์ C (2์๋ฆฌ ์กฐํฉ์ด๋ฏ๋ก ๋ฌด์) →
- B ์ ํ, ๋จ์ ๊ธ์ C
- C ์ ํ, ๋จ์ ๊ธ์ ็ก →
BC
- C ์ ํ, ๋จ์ ๊ธ์ ็ก →
- C ์ ํ, ๋จ์ ๊ธ์ ็ก
์์ฒ๋ผ A, B, C๋ก ๋ง๋ค ์ ์๋ 2์๋ฆฌ ์กฐํฉ์ ์๋ 3๊ฐ์ง๋ค. ์กฐํฉ์ ์์ด๊ณผ ๋ฌ๋ฆฌ ์์์ ์์๋ฅผ ๊ณ ๋ คํ์ง ์์ผ๋ฏ๋ก, ๋์ผํ ์์๋ค์ด ์์๋ง ๋ค๋ฅธ ๊ฒฝ์ฐ๋ฅผ ํ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด์ ๊ณ์ฐํ๋ฉด ์กฐํฉ์ ์๋ฅผ ์ป์ ์ ์๋ค.
์๋ฅผ๋ค์ด A, B, C๋ก ๋ง๋ค ์ ์๋ 2์๋ฆฌ(r=2
) ์์ด์ AB, BA, AC, CA, BC, CB ์ด 6๊ฐ์ง๋ค. ์ด ์์ด์์ [AB, BA], [AC, CA], [BC, CB]์ ๊ฐ์ด ์๋ก ์์๋ง ๋ค๋ฅธ ๊ฒฝ์ฐ๋ค์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด์ ์ฒ๋ฆฌํ๋ฉด ์กฐํฉ์ด ๋๋ค.
๊ฐ ๊ทธ๋ฃน์ $r!$ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋์ด๋ ์ ์๋๋ฐ, ํ ์กฐํฉ(e.g. AB)์ ์์ด์ ๋ ๊ฐ์ง(e.g. AB, BA)๊ฐ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ๋ฐ๋ผ์ ์์ด์ ์ด ์๋ฅผ ๊ฐ ๊ทธ๋ฃน์ ์์ด ์์ธ $r!$๋ก ๋๋๋ฉด ์ค๋ณต์ ์ ๊ฑฐํ ์กฐํฉ์ ์๋ฅผ ๊ณ์ฐํ ์ ์๋ค.
์ ๋ฆฌํ๋ฉด n๊ฐ ์์์์ r๊ฐ๋ฅผ ์ ํํ๋ ์์ด์ ์($_nP_r$)๋ฅผ, $r!$๋ก ๋๋ ์ ์กฐํฉ์ ์($_nC_r$)๋ฅผ ๊ตฌํ ์ ์๋ค. ์ด๋ฅผ ์ํ์ ๊ณต์์ผ๋ก ํ๊ธฐํ๋ฉด $C(n,r) = \frac{_nP_r}{r!} =\frac{n!}{r!(n-r)!}$์ด ๋๋ค. $\frac{n!}{(n-r)!}$์์ ์์ด์ ๋ํ๋ด๊ณ , $(n-r)!$์ ํด๋นํ๋ ํญ์ด ์ฝ๋ถ๋ผ์ $\frac{_nP_r}{r!}$ ํํ๋ก ๋จ์ํ๋๋ค.
$$C(3,2)=\frac{3!}{2!(3-2)!}=\frac{3 \cdot 2 \cdot \cancel{1}}{2 \cdot 1 \cdot \cancel {1}}=3$$
$$C(5,3)=\frac{5!}{3!(5-3)!}=\frac{5 \cdot 4 \cdot 3 \cdot \cancel{2} \cdot \cancel{1}}{3\cdot 2 \cdot 1 \cdot \cancel{2} \cdot \cancel{1}} =10$$
์ค์ํ ์์
- ๋ก๋ ๋ฒํธ : 45๊ฐ ์ซ์ ์ค์์ 6๊ฐ๋ฅผ ๊ณ ๋ฅด๋ ๋ก๋ ์ถ์ฒจ์์ ๊ฐ ์ซ์์ ์์๋ ์ค์ํ์ง ์๋ค. ์ซ์์กฐํฉ [5, 12, 23, 34, 40, 42]์ [42, 34, 23, 12, 5, 40]์ ๋์ผํ ๊ฒฐ๊ณผ๋ก ์ทจ๊ธํ๋ค.
- ์กฐ ๋ฐฐ์ : 30๋ช ์ค์์ 5๋ช ์ผ๋ก ์ด๋ค์ง ์กฐ๋ฅผ ๊ตฌ์ฑํ ๋, ํ ์กฐ์ ์ํ๋ ์ฌ๋์ ์์๋ ์ค์ํ์ง ์๋ค. ์๋ฅผ๋ค์ด [A, B, C, D, E] ๊ทธ๋ฃน๊ณผ [E, D, C, B, A] ๊ทธ๋ฃน์ ๋์ผํ๋ค.
๊ตฌํ
const getCombinations = (arr, combSize, start = 0, curComb = []) => {
if (curComb.length === combSize) return [curComb]; // ๋ชฉํ ํฌ๊ธฐ์ ์กฐํฉ์ ์์ฑํ์ ๋
if (start === arr.length) return []; // ๋์ด์ ์กฐํฉ์ ์์ฑํ ์ ์์ ๋
return arr.slice(start).reduce((allCombs, item, i) => {
const nextComb = curComb.concat(item);
const nextStart = start + i + 1;
return allCombs.concat(getCombinations(arr, combSize, nextStart, nextComb));
}, []);
};
getCombinations(['A', 'B', 'C'], 2); // [['A', 'B'], ['A', 'C'], ['B', 'C']]
/**
* Iteratively generates combinations from an array. This method is typically
* more performant than its recursive counterpart. For example, generating combinations of 2 elements
* from a 1000-element array takes about 100ms iteratively, compared to 600ms functionally.
*/
const getCombinationsIterative = (arr, combSize, start = 0, curComb = []) => {
if (curComb.length === combSize) return [curComb];
const results = [];
const maxIndex = arr.length - combSize + curComb.length;
for (let i = start; i <= maxIndex; i++) {
const nextComb = curComb.concat(arr[i]);
const nextStart = i + 1;
results.push(...getCombinationsIterative(arr, combSize, nextStart, nextComb));
}
return results;
};
- ์
๋ ฅ๋ฐ์ ๋ฐฐ์ด์
start
์ธ๋ฑ์ค๋ถํฐ ์์๋ฅผ ํ๋์ฉ ์ ํํ์ฌ ํ์ฌ ์กฐํฉcurComb
์ ์ถ๊ฐํ๋ค - ์ ํํ ์์ ๋ค์ ์๋ ์์๋ค๋ก ์กฐํฉ์ ์์ฑํ๊ธฐ ์ํด
nextStart
์ธ๋ฑ์ค๋ฅผ ์ ๋ฐ์ดํธํ๋ค - e.g.
['A', 'B', 'C']
๋ฐฐ์ด์์ ์ ํํ ์์๊ฐB
(i=1)๋ผ๋ฉดnextStart
๋ 2๊ฐ ๋๋ค - ํ์ฌ ์กฐํฉ๊ณผ ์ ๋ฐ์ดํธํ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๊ท์ ์ผ๋ก(1~2๊ณผ์ ๋ฐ๋ณต) ์กฐํฉ์ ์์ฑํ๋ค
- ์ฌ๊ท ๊ณผ์ ์ ํตํด ์์ฑ๋ ๋ชจ๋ ์กฐํฉ์ ํ๋์ ๋ฐฐ์ด๋ก ๋ง๋ ํ ๋ฐํํ๋ค
๋ ํผ๋ฐ์ค
์์ด๊ณผ ์กฐํฉ - ์์ด์ด๋ | ์ํ๋ฐฉ
์์ด๊ณผ ์กฐํฉ - ์กฐํฉ์ด๋ | ์ํ๋ฐฉ
๊ธ ์์ ์ฌํญ์ ๋ ธ์ ํ์ด์ง์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ฐ์๋ฉ๋๋ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์
'๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[JS] ๋ฐ๋๋ผ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ง๋ฆฌ์ค ๋ฌ๋ ๊ฒ์ ๊ตฌํํ๊ธฐ
[JS] ๋ฐ๋๋ผ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ง๋ฆฌ์ค ๋ฌ๋ ๊ฒ์ ๊ตฌํํ๊ธฐ
2024.05.29 -
[HTML] select, option ํ๊ทธ ์ฃผ์ ์์ฑ๊ณผ ํน์ง
[HTML] select, option ํ๊ทธ ์ฃผ์ ์์ฑ๊ณผ ํน์ง
2024.05.29 -
[React] ๋ฆฌ์กํธ์์ setTimeout ๋ ํธํ๊ฒ ์ฐ๊ธฐ
[React] ๋ฆฌ์กํธ์์ setTimeout ๋ ํธํ๊ฒ ์ฐ๊ธฐ
2024.05.28 -
[React] ํฌ๋กฌ ํ์ฅ ํ๋ก๊ทธ๋จ ๊ฐ๋ฐ ๋ฐฐ๊ฒฝ ์ง์ ๋ฐ ํํ ๋ฆฌ์ผ
[React] ํฌ๋กฌ ํ์ฅ ํ๋ก๊ทธ๋จ ๊ฐ๋ฐ ๋ฐฐ๊ฒฝ ์ง์ ๋ฐ ํํ ๋ฆฌ์ผ
2024.05.28