1) 소개
* 파워셋(power set) : 어떤 집합의 공집합과 자기자신을 포함한 모든 부분집합.
- 구하고자 하는 집합의 원소 개수 : n => 부분집합 개수 : 2^n
- 백트래킹 기법으로 power set 구하기
- n개의 원소를 포함하는 집합에는 2^n개의 부분 집합이 있음.
- n개의 비트열을 사용하여 부분 집합 표현 가능. (1 또는 0 값을 가지는 n개의 배열을 만드는 방법 이용.)
** 비트열 배열의 i번 인덱스 값 = 집합의 i번 인덱스 원소의 부분 집합 포함 여부 표현.(1:포함, 0:미포함)
ex) 크기가 4인 배열의 부분집합 구하기.
- 자식 노드가 항상 2개인 이진트리.
오른쪽 자식(1) 방문 : 포함, 왼쪽 자식(0) 방문 : 미포함.
높이가 1인 노드 : 첫 번째 원소의 포함 여부를 선택한 상태.
높이가 2인 노드 : 두 번째 원소의 포함 여부를 선택한 상태.
... 총 4번을 선택하면 하나의 부분집합을 표현하게 됨.
루트 ~ 단말 노드 경로에 포함된 4개의 간선에 부여된 값을 모으면 => 하나의 부분집합을 표현하는 비트열이 됨.
* 실제 subset함수의 호출 트리
상태공간트리와 동일함..!
높이 k에 위치한 노드 = k번 선택이 이루어진 상태를 의미함.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* (2) 부분집합 총 원소가 4개인 {A,B,C,D} 집합이 있다. 만들 수 있는 모든 부분집합을 출력하라. */ #include<iostream> using namespace std; char arr[4] = {'A', 'B', 'C', 'D'}; int bit[4]; void subset(int k, int n) { if (k == n) { cout << "{"; for (int i = 0; i < n; i++) { if (bit[i] == 1) { // 부분집합 원소들 사이에 ", " 포함해서 출력하려고.. // A가 첫번째 출력될땐 ", " 출력 안되도록 함. // but, B, C, D가 첫번째 출력될 땐 ", "이 출력된다ㅠㅠ if(i != 0) cout << ", "; cout << arr[i]; } } cout << "}" << endl; } else { bit[k] = 0; subset(k + 1, n); bit[k] = 1; subset(k + 1, n); } } int main() { subset(0, 4); return 0; } | cs |
// 실행 결과
{}
{, D}
{, C}
{, C, D}
{, B}
{, B, D}
{, B, C}
{, B, C, D}
{A}
{A, D}
{A, C}
{A, C, D}
{A, B}
{A, B, D}
{A, B, C}
{A, B, C, D}
계속하려면 아무 키나 누르십시오 . . .
부분집합을 "," 포함해서 이쁘게 출력하는게 잘 안된다.
'알고리즘 > SWExpertAcademy' 카테고리의 다른 글
수영장(DP/DFS) <C/JAVA> (0) | 2018.04.02 |
---|---|
Advanced05 백트래킹 (5) 핵심요약 (0) | 2018.02.17 |
Advanced05 백트래킹 (4) 동전 거스름돈 문제 (0) | 2018.02.17 |
Advanced05 백트래킹 (3) 순열 (0) | 2018.02.15 |
Advanced05 백트래킹 (1)백트래킹 (0) | 2018.02.15 |