알고리즘
[알고리즘] 비트마스킹(Bitmasking)
ghan2
2024. 5. 13. 11:05
비트마스킹이 뭘까? 완전탐색 알고리즘 공부를 하다가 예제에 비트마스킹이 등장했다..
학부때도 비트 연산만 나오면 지루하고 그랬는데.. 계속 피할수만은 없으니!! 이번 기회에 손에 잡힐만하게 공부하자!

비트 연산
더보기
&(AND) : 모두 1이면 1
|(OR) : 하나라도 1이면 1
^(XOR) : 서로 다르면 1
~(NOT) : 반전
비트 이동 연산자
연산식 | 설명 |
x << y | 정수 x의 각 비트를 y만큼 왼쪽으로 이동시킨다. (빈자리는 0으로 채워짐) |
x >> y | 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. (빈자리는 정수 x의 MSB;최상위비트로 채워짐) |
x >>> y | 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. (빈자리는 0으로 채워짐) |
비트마스크란?
비트마스크(bitmask)란 정수의 2진수 표현을 자료구조로 쓰는 기법을 말한다.
- 수행시간이 빠르다.
- 비트마스크 연산은 비트 연산이기 때문에 O(1)에 구현되는 것이 많다. 따라서 다른 자료구조보다 빠르게 동작한다.
- 비트마스크를 사용할 수 있다는 말은 원소의 수가 많지 않다는 뜻이기 때문에 큰 속도 향상을 기대할 수는 없지만, 여러번 수행해야 하는 경우, 큰 속도 향상을 가져올 수 있다.
- 코드가 간결해진다.
- 조건문, 반복문을 사용하지 않고 다양한 집합 연산들을 통해 코드를 간결하게 작성할 수 있다.
- 적은 메모리를 사용한다.
- 비트는 1과 0 두 가지 경우만을 가진다.
- 만약 비트가 10개가 있다면 2^10의 경우를 10비트 이진수 하나로 표현이 가능하다.
- 이 처럼 하나의 정수로 많은 경우의 수를 표현할 수 있기 때문에 메모리 측면에서 효율적이며, 더 많은 데이터를 미리 계산하여 저장해 둘 수 있다는 장점이 있다.
- 이와 같은 특성 덕분에 DP에 매우 유용하다.
적용
import java.util.*;
public class Main {
static int N = 4;
static int[] Nums = {1, 2, 3, 4};
static int solve(int cnt, int used, int val) {
if(cnt == 2) return val;
int ret = 0;
for(int i = 0; i < N; i++) {
if((used & 1 << i) != 0) continue;
ret = Math.max(ret, solve(cnt + 1, used | 1 << i, val * 10 + Nums[i]));
}
return ret;
}
public static void main(String[] args) {
System.out.println(solve(0, 0, 0));
}
}
연산자 우선순위에 따르면 비트 이동 연산자(5순위), 비트AND(8순위), 비트 XOR(9순위), 비트 OR(10순위) 이다.
따라서 1 << i 를 먼저 한 후에 used 와 AND 연산을 한다. AND연산은 모두 1일때 1이 되므로, i번째 비트가 1이면 for문을 빠져나오게 된다.
이 문제에서는 가장 큰 두 자리수를 구해야 하기 때문에 1, 2, 3, 4중 골랐던 숫자는 넘어가도록 해주기 위해 비트 연산이 사용된 예시였다!