Notice
Recent Posts
Recent Comments
Link
Dino Rudy
[ETC] JAVA - 순열,중복 순열 구현 (비트마스크 활용 포함) - 공룡 루디 본문
순열
조합에 이어 알고리즘 문제를 풀 때 많이 쓰이는 순열입니다.
순열은 조합과 다르게 순서가 중요합니다.
순열은 nPr로 표현 할 수 있으며 n개중 r개를 뽑아 나열하는 수열입니다.
구현할 때 조합과 가장 큰 차이점은
isSelected라는 boolean 배열을 만들었다는 점과
조합은 for구문에서 start부터 시작했는데 순열은 i=0부터 시작합니다.
import java.util.Arrays;
public class BasicPermutation {
static int [] selected;
static boolean [] isSelected;
static int count;
static void makePermutation(int[] arr, int R, int cnt) {
//순열을 만들때 끝나는 조건 cnt==R일 때
if(cnt==R) {
count++;
System.out.println(Arrays.toString(selected));
}else {
for(int i=0;i<arr.length;i++) {
if(isSelected[i]) continue;
isSelected[i]=true; //i번째 원소를 선택하고
selected[cnt]=arr[i]; //i번째 원소를 넣고
makePermutation(arr, R, cnt+1); // 재귀 호출
isSelected[i]=false; //i번째 원소 선택 해제
}
}
}
public static void main(String[] args) {
int [] arr = {1,2,3,4,5};
int R = 3;
selected = new int[R]; //selected는 선택된 원소가 들어갈 배열이므로 R개이다.
isSelected= new boolean[arr.length]; //isSelected는 arr의 원소의 개수와 같아야한다.
//배열에 속한 N개의 원소들 중 R개를 뽑아 순열을 만들자
makePermutation(arr,R,0);
System.out.println("순열의 개수: "+count);
}
}
비트 마스크를 활용한 순열 구현
isSelected라는 boolean 배열 대신
비트마스크를 이용하여 순열을 구현 할 수 있습니다.
비트마스크란 2진수의 비트로 이루어진 정수와
쉬프트,&,| 연산을 이용해서 i번째의 플래그가 1인지 0인지 확인하는 방법입니다.
import java.util.Arrays;
public class Permutation_bit_mast {
static int[] selected;
static int count;
static void makePermutation(int [] arr,int R, int cnt, int flag) {
if(cnt==R) {
count++;
System.out.println(Arrays.toString(selected));
}else {
for(int i=0;i<arr.length;i++) {
if((flag&1<<i)!=0) continue; //i번째 플래그가 1인 경우
selected[cnt]=arr[i];
makePermutation(arr, R, cnt+1, flag|1<<i); //i번째 플래그를 1로
}
}
}
public static void main(String[] args) {
int [] arr = {1,2,3,4,5};
int R = 3;
selected = new int[R]; //selected는 선택된 원소가 들어갈 배열이므로 R개이다.
//배열에 속한 N개의 원소들 중 R개를 뽑아 순열을 만들자
makePermutation(arr,R,0,0); // arr R cnt flag
System.out.println("순열의 개수: "+count);
}
}
중복순열 구현
중복순열은
순열을 구현할때 isSelected라는 boolean 배열을 사용 안하면 중복을 허용하게 됩니다.
public class PermutationWithRepitition {
static int[] selected;
static int count;
static void makePermutation(int[] arr, int R, int cnt) {
// 순열을 만들때 끝나는 조건 cnt==R일 때
if (cnt == R) {
count++;
System.out.println(Arrays.toString(selected));
} else {
for (int i = 0; i < arr.length; i++) {
selected[cnt] = arr[i]; // i번째 원소를 넣고
makePermutation(arr, R, cnt + 1); // 재귀 호출
}
}
}
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
int R = 3;
selected = new int[R]; // selected는 선택된 원소가 들어갈 배열이므로 R개이다.
// 배열에 속한 N개의 원소들 중 중복을 허용해 R개를 뽑아 순열을 만들자
makePermutation(arr, R, 0);
System.out.println("중복 순열의 개수: " + count); //개수는 n의 r승임
//n*n*n...*n
}
}
'Algorithm > ETC' 카테고리의 다른 글
[ETC] JAVA - NextPermutation 함수 - 공룡 루디 (2) | 2022.01.08 |
---|---|
[ETC] JAVA - Union-Find - 공룡 루디 (0) | 2021.09.21 |
[ETC] JAVA - 정렬, Comparator - 공룡 루디 (0) | 2021.08.16 |
[ETC] JAVA - 조합 2차원 배열 응용 - 공룡 루디 (0) | 2021.08.14 |
[ETC] JAVA -조합, 중복조합 구현 - 공룡 루디 (0) | 2021.08.13 |