TIL/코딩인터뷰완전분석
[코딩인터뷰완전분석] 18일차. 비트조작
NOHCODING
2023. 9. 26. 03:04
반응형
🐛 비트조작을 해보자
- 1. 0110 + 0110 은 0110 * 2 와 같고, 0110 을 왼쪽으로 한번 shift 하는것과 같다.
- 0100 = 4, 0100 * 4 는 왼쪽으로 두번 shift 하는것과 같다. 따라서 0011 을 왼쪽으로 두 번 shift 하면 1100 이 된다.
- 이 연산은 두개를 따로 생각해야 한다. a ^ (~a) 는 항상 1이 된다.
- ~0 은 모두 1이 된다. (1111) 이 값은 and 연산하면 1000 이다.
🐛 비트조작을 할 때 알아야 할 사실과 트릭들
1s 는 1111 이고, 0s 는 0000 이다. 편의상 4자리 2진수라 가정한다
🐛 2의 보수와 음수
컴퓨터는 정수를 저장할 때 2의 보수 형태로 저장한다. 양수는 문제가 없지만 음수는 절대값에 부호비트를 1로 셋팅한 뒤, 2의 보수를 취한 형태로 표현한다.
🐛 산술 우측 시프트 VS 논리 우측 시프트
- 산술 우측 시프트(arithmetic right shift)
- 논리 우측 시프트(logical right shift)
🐛 기본적인 비트 조작 : 비트값 확인 및 채워 넣기
비트값 확인
- 1을 i 만큼 왼쪽으로 shift 하여 0001000 과 같이 만든다 → num과 & 연산을 하여 i 번째 위치 숫자를 제외하고 모두 삭제한다. → 이 값이 1이면 num 의 i 번째 비트는 1이 포함된 숫자이고, 0이면 num 의 i 번째는 0이 포함되었다.
boolean getBit(int num, int i) {
return ((num & (1 << i)) != 0);
}
비트값 채워넣기
- 특정 i 번째 위치에 1을 채워넣는다. 1을 왼쪽으로 shift 하여 001000 과 같이 만들어 or 연산을 한다. 0인 곳은 기존의 값에 영향을 주지 못한다.
int setBit(int num, int i) {
return num | (1 << i);
}
비트값 삭제하기
- 특정 bit 만 삭제한다. getBit 를 반대로 했다. 001000 을 ~ 연산자를 사용해 110111 으로 만들어 and 연산을 하여 특정 위치의 bit 를 제거한다.
int clearBit(int num, int i) {
int mask = ~(1 << i);
return num & mask;
}
- 최상위 비트에서 i번째 비트까지 모두 삭제하기
- i 번째 bit 를 셋팅하고 -1 을 하면 최상위 부터 i 번째 까지 0으로 채워지고, 그 뒤는 1로 채워진다. 이 값을 num에 & 연산을 하면 앞을 0 때문에 0으로 지워지고 그 뒤는 모두 1 때문에 그대로 남아 있는다.
int clearBitsFromHead(int num, int i) {
int mask = (1 << i) - 1;
return num & mask;
}
- 0 ~ i 까지의 bit 를 전부 삭제한다. 비트가 모두 1 이면 10진수로 -1 이 된다. -1에 i+1 만큼 시프트 시킨 후 그 값을 & 연산한다.
int clearBitFromTail(int num, int i) {
int mask = (-1 << (i+1));
return num * mask;
}
- i번째 bit 를 v로 변경하기
int updateBit(int num, int i, boolean bitIs1) {
int value = bitIs1 ? 1 : 0;
int mask = ~(1 << 1);
return (num & mask) | (value << i);
}
🏅문제풀이
5.1 삽입
public int bitInsert(int m, int n, int i, int j) {
m = bitDeleteFrom(m, j, i);
n = leftBitShift(n, i);
System.out.println("m: " + Integer.toBinaryString(m) + ", n: " + Integer.toBinaryString(n)
+ ", m + n: " + Integer.toBinaryString(m+n));
return m + n;
}
private int bitDeleteFrom(int num, int start, int end) {
int mask = (1 << (start + 1)) - 1;
mask = mask >> end;
mask = mask << end;
return num & ~mask;
}
private int leftBitShift(int num, int j) {
return num << j;
}
5.3 비트 뒤집기
private String convert1bit(int data) {
String[] d = String.valueOf(data).split("0");
int max = 0;
int maxIndex = 0;
for (int i = 0; i < d.length; i++) {
if (d[i].length() > max) {
max = d[i].length();
maxIndex = i;
}
}
String result = "";
if (maxIndex < d.length-1 && d[maxIndex+1] != "") {
result = d[maxIndex] + "1" + d[maxIndex+1];
}
if (maxIndex > 0 && d[maxIndex-1] != "") {
String re = d[maxIndex-1] + "1" + d[maxIndex];
if (result.length() < re.length()) {
return re;
}
}
return result;
}
Integer.toBinaryString(1024);
반응형