비트 연산은 컴퓨터의 기본 연산이기 때문에 속도가 빠릅니다.
예시는 다음과 같습니다. ( 5 & 6 )
101 (5)
110 (6)
and ----------
100 (4)
예시는 다음과 같습니다. ( 5 | 6 )
101 (5)
011 (3)
or ----------
111 (7)
주로 x를 상태 반전할 때 사용합니다.
예시는 다음과 같습니다. (5 ^ 3)
101 (5)
011 (3)
xor ----------
110 (6)
값이 두배가 됩니다.
예시는 다음과 같습니다.
5 = 0000101 (5)
5 << 1 = 0001010 (10)
5 << 2 = 0010100 (20)
5 << 3 = 0101000 (40)
값이 1/2배 됩니다.
예시는 다음과 같습니다.
13 = 0001101 (13)
13 >> 1 = 0000110 (6)
13 >> 2 = 0000011 (3)
13 >> 3 = 0000001 (1)
정수 하나를 표현하기 위해 32bit를 사용합니다.
만약 0~31까지의 요소를 중복 없이 사용하는 문제가 주어진다면 두가지 방법으로 해결할 수 있습니다.
비트 마스킹으로 사용여부를 표현한다면 다음과 같이 사용할 수 있습니다.
x 상황
00000000000000000000000000000000 (0) : 아무 수도 없는 경우
00000000000000000000000000001010 (10) : 1, 3만 있는 경우
00000000000000000000000000100111 (39) : 0, 1, 2, 5만 있는 경우
00000000000000000000000001000000 (64) : 6만 있는 경우
현재 수 2가 존재하는지 x를 통해서 알아보고자합니다.
이 경우에는 간단하게, 오른쪽에서 3번째 수가 1인지를 알아내면됩니다.
right shift 연산자를 이용해 x를 오른쪽으로 2칸 밉니다.
x 00000000000000000000000000100111 (39)
x >> 2 00000000000000000000000000001001 (9)
가장 오른쪽 bit가 1인지 확인합니다.
x 00000000000000000000000000100111 (39)
x >> 2 00000000000000000000000000001001 (9)
(x >> 2) & 1 00000000000000000000000000000001 (1)
어떤 수가 주어졌을 때 가장 마지막 bit를 찾아내는 방법은 알아내기 원하는 bit에만 1을 넣고 나머지에 전부 0을 넣었을 때 나오는 값과 and 연산을 진행합니다.
만약 존재하지 않는 경우의 연산은 다음과 같이 진행됩니다.
x 00000000000000000000000000100011 (35)
x >> 2 00000000000000000000000000001000 (8)
(x >> 2) & 1 00000000000000000000000000000000 (0)
0,1,2,5만 있는 경우에서 4를 추가해봅시다.
오른쪽에서 5번째 bit만 1인 수를 만든 뒤, 기존 x와 이 수를 더합니다.
x 00000000000000000000000000100011 (35)
1 << 4 00000000000000000000000000010000 (16)
x + (1 << 4) 00000000000000000000000000110011 (51)
정리
즉, x ^ (1 << k)는 수 k가 있다면 없애고, 없다면 새로 만들어주는 역할을 해주게 됩니다.
(1 << 5) - 1 00000000000000000000000000011111 (31)
숫자들의 총합과 숫자들의 or 연산 값이 같습니다.
문제 보러가기
->
https://www.codetree.ai/missions/9/problems/bit-calculation?&utm_source=clipboard&utm_medium=text
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokens;
private static int add(int set, int data){
if(print(set,data)==1) return set;
return set^(1<<data);
}
private static int delete(int set, int data){
if(print(set,data)==0) return set;
return set^(1<<data);
}
private static int print(int set, int data){
return (set>>data)&1;
}
private static int toggle(int set, int data){
return set^(1<<data);
}
private static int clear(){
return 0;
}
public static void main(String[] args)throws IOException {
int commandNum = Integer.parseInt(buffer.readLine());
StringBuilder result = new StringBuilder();
int set = 0;
for(int commandIdx = 0 ; commandIdx<commandNum; commandIdx++){
tokens = new StringTokenizer(buffer.readLine());
String command = tokens.nextToken();
if(command.equals("add")){
int data = Integer.parseInt(tokens.nextToken());
set = add(set, data);
}else if(command.equals("delete")){
int data = Integer.parseInt(tokens.nextToken());
set = delete(set, data);
}else if(command.equals("print")){
int data = Integer.parseInt(tokens.nextToken());
result.append(print(set, data)).append("\n");
}else if(command.equals("toggle")){
int data = Integer.parseInt(tokens.nextToken());
set = toggle(set, data);
}else if(command.equals("clear")){
set = clear();
}
}
System.out.println(result);
}
}```
ㅣ