n개의 값 중에서 r 개의 숫자를 순서를 고려해 나열한 경우의 수
nPr = n x n-1 x n-2 ...... x n-r+1
EX) {1,2,3} 총 3개의 값 중에서 3개의 숫자를 순서를 고려해 나열하면
1 2 3 / 1 3 2 / 2 1 3 / 2 3 1 / 3 1 2 / 3 2 1 로 총 6개 로 나타낼 수 있다 (3! = 1x2x3)
swap 함수를 만들어서 배열들의 값을 직접 바꾸는 방법
배열의 첫 값부터 순서대로 하나씩 바꾸며 모든 값을 한번씩 swap
순열들의 순서가 보장되지 않는다 EX) C,A,B 가 먼저 나오는 게 아니라 C,B,A 가 먼저 노출됨
#include <stdio.h>
void swap(int arr[], int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void perm(int arr[], int depth, int n, int k) {
if (depth == k) {
for(int i=0;i<n;i++) {
printf("%d", arr[i]);
}
printf("\n");
return;
}
for(int i = depth; i < n;i++) {
swap(arr, i, depth); // 배열을 depth 에 따라 변경
perm(arr, depth+1, n, k); // 재귀 함수
swap(arr, i, depth); // 변경된 배열을 다시 원복
}
}
int main() {
int arr[] = {1,2,3};
perm(arr, 0, sizeof(arr) / 4 ,2);
return 0;
}
변수 | 설명 |
---|---|
arr | 순열 알고리즘 적용할 배열 |
depth | 현재 깊이 |
n | 배열 안에 들어 있는 숫자 갯수 (고정) |
k | 몇 depth 까지 보여줄지 설정 (고정) |
visited 변수 사용
DFS = 깊이 우선 탐색, 한 노드의 자식을 끝까지 순회한 후 다시 돌아와서 다른 형제들의 자식을 타고 내려가면서 순회
#include <stdio.h>
void perm(int arr[], bool visited[], int output[], int depth, int n, int k) {
if (depth == k) {
for(int i=0;i<n;i++) {
printf("%d ", output[i]);
}
printf("\n");
return;
}
for (int i=0;i<n;i++) {
if (visited[i] != true) {
visited[i] = true;
output[depth] = arr[i];
perm(arr, visited, output, depth + 1, n, k); // 재귀 함수
visited[i] = false; // 중복 확인 배열
}
}
}
int main() {
int n = 3;
int arr[] = {1,2,3};
bool visited[n];
int output[n];
perm(arr, visited, output, 0, n, 3);
}
변수 | 설명 |
---|---|
arr | r 개를 뽑기 위한 n 개의 값이 저장된 배열 |
output | r개의 사이즈 배열 |
visited | 중복해서 뽑지 않기 위해 체크하는 배열 |
O(n!)
➡ nPr 이기 때문에