C & C++
[C++] 재귀함수를 이용한 조합
Chunghyun Lee
2024. 7. 17. 15:38
조합(combination)은 특정 집합에서 순서를 고려하지 않고 선택한 부분집합을 의미합니다.
이 글에서는 재귀함수를 이용한 조합 생성 코드를 설명합니다.
함수 정의
void combi(int start, vector<int> b) {
if (b.size() == k) {
print(b);
return;
}
for (int i = start + 1; i < n; i++) {
b.push_back(i);
combi(i, b);
b.pop_back();
}
}
주요 요소
- start: 현재 조합에서 다음 요소를 선택하기 시작할 위치를 의미합니다.
- b: 현재까지 선택된 요소들을 저장하는 벡터입니다.
- k: 선택할 요소의 개수입니다.
- n: 선택 가능한 전체 요소의 개수입니다.
- print(b): 완성된 조합을 출력하는 함수입니다.
작동 원리
- 조합의 완성 조건:
- if (b.size() == k) 부분에서 현재 조합이 완성되었는지 확인합니다. 조합의 길이가 원하는 길이 k에 도달하면 print(b)를 호출하여 조합을 출력합니다.
- 재귀 호출을 통한 조합 생성:
- for (int i = start + 1; i < n; i++) 반복문을 통해 현재 요소 다음의 요소들을 순회합니다.
- b.push_back(i)를 통해 현재 요소 i를 조합에 추가합니다.
- combi(i, b)를 재귀 호출하여 다음 요소를 추가합니다.
- b.pop_back()를 통해 마지막에 추가한 요소를 제거하여 다음 반복을 준비합니다.
예제 코드
다음은 위 함수와 함께 사용할 수 있는 예제 코드입니다:
#include <bits/stdc++.h>
using namespace std;
int n, k;
void print(const vector<int>& b) {
for (int num : b) {
cout << num << ' ';
}
cout << endl;
}
void combi(int start, vector<int>& b) {
if (b.size() == k) {
print(b);
return;
}
for (int i = start + 1; i < n; i++) {
b.push_back(i);
combi(i, b);
b.pop_back();
}
}
int main() {
n = 5; // 예: n = 5
k = 3; // 예: k = 3
vector<int> b;
combi(-1, b); // 초기 start 값은 -1 (첫 번째 요소가 0부터 시작하게 하기 위함)
return 0;
}
코드 설명
- 메인 함수 설정:
- n과 k 값을 설정합니다. 여기서는 n = 5와 k = 3으로 설정하였습니다.
- vector<int> b는 현재 조합을 저장할 벡터입니다.
- combi(-1, b)를 호출하여 조합 생성을 시작합니다. -1을 시작값으로 하여 첫 번째 요소가 0부터 시작하도록 합니다.
- 조합 생성 및 출력:
- combi 함수는 재귀적으로 호출되며, b.size()가 k에 도달할 때마다 print 함수가 호출되어 조합을 출력합니다.
- print 함수는 벡터 b의 모든 요소를 출력합니다.
조합 생성의 예
n = 5와 k = 3인 경우, 생성되는 조합은 다음과 같습니다:
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
함수 동작의 도식화
다음은 n = 5, k = 3인 경우의 재귀 호출 과정을 도식화한 것입니다:
combi(-1, [])
├ combi(0, [0])
| ├ combi(1, [0, 1])
| | ├ combi(2, [0, 1, 2]) -> print [0, 1, 2]
| | ├ combi(3, [0, 1, 3]) -> print [0, 1, 3]
| | └ combi(4, [0, 1, 4]) -> print [0, 1, 4]
| ├ combi(2, [0, 2])
| | ├ combi(3, [0, 2, 3]) -> print [0, 2, 3]
| | └ combi(4, [0, 2, 4]) -> print [0, 2, 4]
| └ combi(3, [0, 3])
| └ combi(4, [0, 3, 4]) -> print [0, 3, 4]
├ combi(1, [1])
| ├ combi(2, [1, 2])
| | ├ combi(3, [1, 2, 3]) -> print [1, 2, 3]
| | └ combi(4, [1, 2, 4]) -> print [1, 2, 4]
| └ combi(3, [1, 3])
| └ combi(4, [1, 3, 4]) -> print [1, 3, 4]
└ combi(2, [2])
└ combi(3, [2, 3])
└ combi(4, [2, 3, 4]) -> print [2, 3, 4]
결론
재귀함수를 이용한 조합 생성은 C++에서 매우 직관적이고 이해하기 쉬운 방법입니다. 이를 통해 원하는 길이의 조합을 효율적으로 생성하고 출력할 수 있습니다. 이러한 방법은 알고리즘 문제 해결 및 조합론적 문제를 풀 때 매우 유용합니다.