본문 바로가기

Programming

[Algorithm] 알고리즘 준비 03. 순열

728x90
반응형

순열

순열이란?

- 1 ~ N 까지 이루어진 순열

- 크기는 항상 N이며 겹치는 숫자는 존재하지 않음

- 크기가 N인 순열은 총 N!개가 존재


다음 순열 찾는 법

- 배열 A[N]에서

- A[i-i] < A[i] 를 만족 하는 i 중 가장 큰 값을 i 값 찾음

- j >= i 이면서 A[j] > A[i-1]을 만족하는 가장 큰 j 값을 찾음

- A[i-1]과 A[j] 값을 swap 한다.

- A[i] 부터 순열을 뒤집는다.



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
bool next_permutation(vector<int> &a, int n) {
    int i = n-1;
    
    // A[i-1] > A[i]를 만족하는 가장 큰 i 값을 찾기 위해 뒤에서 부터 탐색
    while (i > 0 && a[i-1>= a[i]) {
        i -= 1;
    }
    if (i <= 0) {   // 마지막 순열
        return false
    }
    int j = n-1;
    // j> i 이면서 A[j] > A[i-1]을 만족하는 j 값 중 가장 큰 값 탐색
    while (a[j] <= a[i-1]) {
        j -= 1;
    }
    swap(a[i-1], a[j]);  // swap
    j = n-1;
 
    while (i < j) { // swap
        swap(a[i], a[j]);
        i += 1
        j -= 1;
    }
    return true;
}
cs


 순열을 이용한 조합(Combination)

- 순열을 이용해서 조합을 구함

- 0일 경우에만 출력


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
#pragma warning (disable : 4996)
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    vector<int> v; 
    vector<int> no;
    
    for (int i = 1; i <= 10; i++)    // 10개 추가
    {
        v.push_back(i);
    }
    // 0 8개, 1 2개
    for (int i = 1; i <= 8; i++)
    {
        no.push_back(0);
    }
    for (int i = 1; i <= 2; i++)
    {
        no.push_back(1);
    }
    sort(no.begin(), no.end());
    // 10개중에 8개 뽑는 경우의 수
    do {
        for (int i = 0; i < 10; i++) {
            if (no[i] == 0printf("%d ", v[i]);
        }
        printf("\n");
    } while (next_permutation(no.begin(), no.end()));
    return 0;
}
cs


반응형