비트마스킹의 개념을 알아두면 

값 하나에 여러가지 상태를 표시하는 기법을 알 수 있게 된다.

비트마스킹을 이용한 대표적인 문제가 외판원 순회(TSP) 인 것 같다.

 

예를 들어 집이 4개가 있고, 집 번호를 0~3, 이 집들을 방문한 정보들을 알고 싶다고 할 때,

우리는 비트마스킹 즉, 비트라는 값을 이용해서 하나의 값으로 여러 상태를 표현할 수 있다.

우선 집이 4개 => 4개의 집에 대한 정보를 표현하기 위한 크기가 필요하다.

이를 4비트(2^4 = 16(0~15))로 표현해보자

이 때, 4비트에 대한 비트 표현법은 1<<4 (2^4) 가 된다.

 

만약 0번 집만 방문했다면 0001 (실제로는 1이 저장된다)

만약 1번 집만 방문했다면 0010 (실제로는 2가 저장된다)

만약 1, 3번 집만 방문했다면 1010 (실제로는 2^1+2^3 => 10이 저장된다)

 

여기서 비트1은 방문을 했고 비트0은 방문을 하지 않았음을 나타낸다.

 

비트마스킹 정보를 배열에 저장한다고 가정하면 array[1<<4] 와 같이 선언하여 사용하면 된다.

 

----------- 연산 -------------

 

어떤식으로 사용되는지 알았다면, 이용할 수 있는 연산이 뭐가 있는지 알아보자

 

기본적인 비트연산은 알고 있을 것이다.

&연산의 의미는 두 비트값 모두 1이면 1, 아니면 0을 반환하고

| 연산의 의미는 둘중 한 값이라도 1이면 1, 아니면 0을 반환하고

~연산의 의미는 모든비트를 뒤집는 연산 0->1, 1->0 을 반환하게 된다.

 

비트의 크기는 N, 현재 비트값을 current 라고 할 때

 

. 모든 비트가 1인지 확인해보고 싶다 => current & (1<<N)-1 

 

. 모든 비트가 0인지 확인해보고 싶다 => current & 0

 

. K번째 비트가 1인지 0인지 확인해보고 싶다 => current & (1<<K)

K번째 비트만 둔채로 나머지 비트는 다 버려야 된다

이때 1<<K 의 의미는 K번째 비트만 1 처리하고 나머지 비트는 0 처리한다는 뜻이다.

(만약 K가 4라면 1<<4 => 16이 되고, 이를 비트로 나타내면 10000 (= 16) 가 된다는 뜻이다.

N이 4보다 큰 값이라고 할 때 좀더 정확히는 ...0000...0010000 이라는 의미가 된다)

 

. K번째 비트를 1로 만들고 싶다 => current | (1<<K)

위의 설명을 이해했다면 | (OR) 연산자를 사용해야 함을 알 수 있을 것이다.

K번째 비트를 1로 만들고 싶다면 K번째 비트를 1로 만들고 나머지 비트는 current 값 그대로 가져오면 된다.

 

. K번째 비트를 0으로 만들고 싶다 => current & ~(1<<K)

K번째 비트를 1로 만든 후, NOT연산 ~을 이용하여 뒤집어버리면

K번째 비트만 0이 되고 나머지는 1이 된다.

& 연산을 하면 K번째 비트는 강제로 0이 될 것이고, 나머지 비트들은 원래 값을 가지게 된다.

'algorithm > algorithm' 카테고리의 다른 글

Point in a Polygon - 다각형 내부점 판단  (0) 2020.04.07
좌표 시계/반시계방향 정렬  (0) 2020.04.07
소인수분해  (0) 2020.02.28
기본 기하 공식  (0) 2020.02.28
볼록껍질 선분 처리하기  (0) 2020.02.28

+ Recent posts