조합
순열은 STL에 구현되어있는 next_permutation을 사용하면 되지만, 조합은 STL에 따로 구현된 함수가 없어서 따로 구현해야 한다.
조합의 구현은 next_permutation을 활용한 방법과 재귀를 활용한 방법 두가지가 있다.
1. next_permutation
을 활용한 조합 생성
방법 설명
- 주어진 배열을 정렬한 후, 특정 개수만큼의
1
과0
으로 비트마스크를 만든 다음, 이 마스크를 통해 가능한 모든 조합을 생성하는 방식입니다.
- 예를 들어,
5C3
조합을 구하려면[0, 0, 0, 1, 1]
과 같은 배열을 만들고,next_permutation
을 통해 배열의 모든 순열을 탐색합니다. 이때1
이 위치한 인덱스의 요소들을 조합으로 선택합니다.
구현 예시
#include <iostream> #include <vector> #include <algorithm> #include <numeric> using namespace std; int main() { vector<int> arr = { 1, 2, 3, 4, 5 }; //5C3 vector<int> bin = { 0, 0, 0, 1, 1 }; do { int index = 0; for (auto i : bin) { if (i == 0) { cout << arr[index] << ' '; } index++; } cout << "\n"; } while (next_permutation(bin.begin(), bin.end())); return 0; }
2. 재귀를 사용한 조합 생성
방법 설명
- 조합을 생성할 때마다 직접적으로 배열에서 필요한 요소만 선택해 나가는 방식입니다.
- 현재 위치에서 다음 요소를 선택할지 말지를 결정하면서 모든 조합을 탐색합니다.
구현 예시
void Collaboration(vector<int>& target, vector<int>& selected, int depth, int next, int r) { if (depth == r) { PrintArray(selected); return; } for (int i = next; i < target.size(); ++i) { selected.push_back(target[i]); Collaboration(target, selected, depth + 1, i + 1, r); selected.pop_back(); } }
ㅤ | next_permutation | recurtion |
장점 | 구현이 간단함
모든 조합을 사전식으로 구할 수 있음
특정 순서대로 탐색할 수 있음 | 필요한 최소한의 연산만 수행
메모리 사용량과 연산량이 비교적 적음
요소의 수가 크거나 조합의 크기가 작을 때 효율적 |
단점 | 배열이 길면 비트마스크 크기가 커지고 불필요한 연산이 많아짐
순열을 매번 생성해야 하므로, 불필요한 계산이 발생 | 어려울 수 있고, 구현이 비교적 복잡함
조합의 순서를 정렬하지 않으면, 순서가 보장되지 않을 수 있습니다. |