10진법과 2진법 테이블(32bit signed short기준)
0 : 00000000 00000000 ..... 32761 : 01111111 11111001 32767 : 01111111 11111111 (max) -32768 : 10000000 00000000 (min) -32767 : 10000000 00000001 -32766 : 10000000 00000010 -32765 : 10000000 00000011 -32764 : 10000000 00000100 -32763 : 10000000 00000101 ..... -5 : 11111111 11111011 -4 : 11111111 11111100 -3 : 11111111 11111101 -2 : 11111111 11111110 -1 : 11111111 11111111 0 : 00000000 00000000 ......
|
문제 : int 값 n이 주어졌을 때, n의 비트를 출력하라.
아래 코드와 같은 방식으로, 오른쪽으로 한 칸씩 옮겨가며 1과 & 연산한 값을 stack 에 저장해두고 출력하면 된다.
|
public String printBit(int num){
StringBuilder sb = new StringBuilder();
for(int i=0; i<32; i++){
sb.append(num&1);
num>>>=1;
}
return sb.reverse().toString();
}
혹은 아래 사이트에 정리가 잘 되어 있으니 이 사이트의 내용을 참고한다.
|
문제 : 정수 N 의 비트 값에서 1의 개수를 구하라.
정수 N 을 오른쪽 shift 해가면서 1과 and(&) 연산했을 때 1이면 count를 올리는 식으로 구현이 가능하다.
for(int i=n; i!=0; i>>>=1){ if( (i & 1) == 1) count++; }
재밌게도 위의 방법 외에 아래처럼 n & (n-1) 을 계속 해가며 0으로 만드는 횟수를 셀 수도 있다. 직관적으로 이게 왜 되는지 이해는 안 되지만 -_-;
for(int i=n; i!=0; i= i & (i-1) ){ count++; }
|
문제 : 숫자 n 이 주어진다. 모든 bit 가 1인 변수를 만들고, 아래에서 n개 만큼만 0으로 만들어라. 예를 들어 n 이 3일 때 1111 1000 n이 5일 때 1110 0000
모든 bit 가 1인 변수는 -1이다. (-1 의 bit 는 1111 1111) 혹은 ~0 을 대신 사용해도 좋다.
여기서 n 만큼 왼쪽 shift 연산을 사용하면 << 된다.
|
문제 : 숫자 n 이 주어진다. 모든 bit 가 0인 변수를 만들고, 아래에서 n개 만큼만 1로 만들어라. 예를 들어 n 이 3일 때 0000 0111 n이 5일 때 0001 1111
아래 코드처럼 1을 n번씩 옮겨가며 더해줘도 된다.
int n = 6;
혹은 아래 코드로, n개의 1을 갖는 값을 한번에 만들어서 더해줘도 된다.
int n = 6;
(0100 0000을 만든 후 -1을 하면 0011 1111이 되기 때문에 한 번에 n개의 1을 만들 수 있다.) |
문제 : ((n & (n-1))==0) 이 무엇을 하는 코드인지 설명하라.
바로 위에서 설명한 것처럼, 1<<6 같은 2의 배수값에서 -1을 하면 0의 bit 개수만큼 1이 채워지게 된다. 예를 들어 비트가 1000 인 값 8에서 -1을 하면 비트가 0111 인 7이 된다. 따라서 2의 배수값에서 -1한 값과 &을 하게되면 무조건 0이 나오게 된다. 위의 코드는 이 사실을 토대로, n이 2의 배수인지 아닌지를 확인하는 코드이다.
추가적으로 n이 0일때 -1을 하면 1111 1111 을 얻을 수 있고 & 하면 0이 된다. 따라서 위의 코드를 통해 n 이 0인지 아닌지 확인할 수 도 있다. |
문제 : 정수 A를 정수 B로 변환하기 위해 바꿔야 하는 bit의 개수를 구하는 코드를 작성하라.
xor 를 이용하여 간단하게 풀 수 있다. 정수 A 에서 정수 B로 바꾸려면 bit가 다른 위치의 bit만 0->1 , 1->0 으로 바꿔주면 되는데 AxorB(A^B) 를 이용하면 그 다른 위치에만 1 값이 들어가게 된다.
아래 코드를 보자. |
short a = 20061;
short b = -9179;
printBit(a); //01001110 01011101
printBit(b); //11011100 00100101
short c = (short) (a^b);
printBit(c); //10010010 01111000
int sum=0;
for(int i=0; i<16; i++){
if((c&1)==1) sum++;
c>>>=1;
}
System.out.println(sum); //7
//아래는 개선된 코드
for(short c = (short)(a^b); c!=0; c>>=1){
sum++;
}
'Coding Interview' 카테고리의 다른 글
[Baekjoon] 2156번 포도주 시식 (0) | 2020.01.30 |
---|---|
[Baekjoon] 11727번 2×n 타일링 2 (0) | 2020.01.27 |
[Coding Interview] 트리 관련 문제 (0) | 2020.01.26 |
[JAVA] 같은 역할을 하지만 무거운 연산들 (0) | 2020.01.24 |
[leetcode] linked-list-cycle (0) | 2020.01.19 |