1. 순열(Permutation)
순열
- 서로 다른 n개 중 r개를 순서를 고려하여 선택하는 것
- n = 6, r = 4 이면, P(6, 4) = 6 X 5 X 4 X 3 = 360
- 경우의 수가 11! 이 넘으면 순열로 풀 수 없음(경우의 수: 4억 이상)
코드로 보는 순열
- 원소와 N, R이 주어졌을 때 순열을 구하는 코드
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static int N, R;
static boolean[] isSelected;
static int[] input, output;
private static void permutation(int cnt){
if(cnt == R){ // R개를 뽑았을 때
System.out.println(Arrays.toString(output));
return;
}
for(int i=0; i<N; i++){
if(isSelected[i]){ // 이미 뽑은 원소라면 제외
continue;
}
isSelected[i] = true;
output[cnt] = input[i]; // 뽑은 후 결과 배열에 넣기
permutation(cnt+1);
isSelected[i] = false;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
R = sc.nextInt();
isSelected = new boolean[N];
input = new int[N];
output = new int[R];
for(int i=0; i<N; i++){
input[i] = sc.nextInt();
}
permutation(0);
}
}
/*
input
3
2
1 2 3
output
[1, 2]
[1, 3]
[2, 1]
[2, 3]
[3, 1]
[3, 2]
*/
중복 순열
- 서로 다른 n개 중 r개를 순서를 고려하여 선택하는데 이미 선택한 것을 중복해서 선택하는 것을 허용
- 순열을 구하는 코드에서 값이 중복인지 체크하는 코드를 빼면 됨
코드로 보는 중복 순열
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static int N, R;
// static boolean[] isSelected; // 중복 허락이므로 주석처리
static int[] input, output;
private static void permutation(int cnt){
if(cnt == R){ // R개를 뽑았을 때
System.out.println(Arrays.toString(output));
return;
}
for(int i=0; i<N; i++){
// if(isSelected[i]){ // 중복 체크 부분 주석처리
// continue;
// }
// isSelected[i] = true;
output[cnt] = input[i]; // 뽑은 후 결과 배열에 넣기
permutation(cnt+1);
// isSelected[i] = false;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
R = sc.nextInt();
// isSelected = new boolean[N];
input = new int[N];
output = new int[R];
for(int i=0; i<N; i++){
input[i] = sc.nextInt();
}
permutation(0);
}
}
/*
input
3
2
1 2 3
output
[1, 1]
[1, 2]
[1, 3]
[2, 1]
[2, 2]
[2, 3]
[3, 1]
[3, 2]
[3, 3]
*/
2. 조합(Combination)
조합
- 서로 다른 n개 중 r개를 순서 없이 선택하는 것
- n = 6, r = 4 이면, C(6, 4) = 6!/(4!X2!) = 15
- 조합의 재귀적 표현 : nCr = (n-1)C(r-1) + (n-1)C(r)
코드로 보는 조합
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static int[] tmp;
static int[] arr;
static int n;
static int r;
private static void combination(int cnt, int idx){
if(cnt == r){
System.out.println(Arrays.toString(tmp));
return;
}
for(int i=idx; i<n; i++){
tmp[cnt] = arr[i];
combination(cnt+1, i+1);
}
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
r = sc.nextInt();
arr = new int[n];
tmp = new int[2];
for(int i=0; i<n; i++){
arr[i] = sc.nextInt();
}
combination(0,0);
}
}
중복 조합
- 서로 다른 n개 중 r개를 순서를 고려없이 선택하는데 이미 선택한 것을 중복해서 선택하는 것을 허용
코드로 보는 중복 조합
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static int[] tmp;
static int[] arr;
static int n;
static int r;
private static void combination(int cnt, int idx){
if(cnt == r){
System.out.println(Arrays.toString(tmp));
return;
}
for(int i=idx; i<n; i++){
tmp[cnt] = arr[i];
combination(cnt+1, i); // 조합은 i+1부터, 중복조합은 i부터
}
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
r = sc.nextInt();
arr = new int[n];
tmp = new int[2];
for(int i=0; i<n; i++){
arr[i] = sc.nextInt();
}
combination(0,0);
}
}
3. 부분 집합(Subset)
부분 집합
- 집합에 포함된 원소들을 선택하는 것
- 원소가 n개일때 부분집합의 개수는 2^n
코드로 보는 부분 집합
import java.io.IOException;
import java.util.Scanner;
public class Test {
static boolean[] isSelected;
static int[] arr;
static int n;
private static void SubSet(int cnt, int idx){
if(idx == n){
for(int i=0; i<n; i++){
if(isSelected[i]){
System.out.print(arr[i]+" ");
}
}
System.out.println();
return;
}
SubSet(cnt, idx+1); // 선택 안함
isSelected[idx] = true;
SubSet(cnt+1, idx+1); // 선택 함
isSelected[idx] = false;
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
arr = new int[n];
isSelected = new boolean[n];
for(int i=0; i<n; i++){
arr[i] = sc.nextInt();
}
SubSet(0,0);
}
}
/*
[input]
3
1 2 3
[output]
3
2
2 3
1
1 3
1 2
1 2 3
*/
'Computer Science > Algorithm' 카테고리의 다른 글
[Algorithm] 나머지 연산과 페르마의 소정리 (0) | 2022.04.11 |
---|