본문 바로가기

문제 풀기/코딩인터뷰

[코딩인터뷰 완전정복] 5.1 삽입

Q : 두 개의 32비트 수 N과 M이 주어지고, 비트 위치 i와 j가 주어졌을 때, M을 N에 삽입하는 메서드를 구현하라. M은 N의 j번째 비트에서 시작하여 i번째 비트에서 끝난다. j번째 비트에서 i번째 비트까지에서 M을 담기 충분한 공간이 있다고 가정한다. 다시 말해, M=10011이라면, j와 i사이에 적어도 다섯 비트가 있다고 가정해도 된다는 것이다. j = 3이고 i = 2인 경우처럼 M을 삽입할 수 없는 상황은 생기지 않는다고 봐도 된다.

 

1. 입력값이 10진수로 표현된 비트 인 경우

j와 i사이에 충분한 공간이 있다는 가정이므로 M에 10^(i-1)만큼 곱해서 N에 더해주면 된다.

이때, M이 들어갈 자리에 있는 N의 비트값을 지워준다.

#include <iostream>
#include <cmath>

int main() {
	int N, M;
	int i, j;

	printf("input N : ");
	scanf_s("%d", &N);
	printf("input M : ");
	scanf_s("%d", &M);

	printf("input i : ");
	scanf_s("%d", &i);
	printf("input j : ");
	scanf_s("%d", &j);

	int pointer = pow(10, i - 1);
	for (int k = i; k <= j; k++) {
		if ((N / pointer) % 2 == 1) N -= pointer;
		pointer *= 10;
	}

	N += M * (pow(10,i-1));

	printf("%d\n", N);

}

 

2. 10진수 값이 주어지고, 비트연산을 통해 계산하는경우

마찬가지로 j와 i사이에 충분한 공간이 있다는 가정이므로 M에 <<(쉬프트) 연산 (i-1)번을 해준뒤 N에 더해준다.

N의 기존 값을 지울때는 마스크를 만들어서 N과 &(엔드연산) 해준다.

#include <iostream>

int main() {
	int N, M;
	int i, j;

	printf("input N : ");
	scanf_s("%d", &N);
	printf("input M : ");
	scanf_s("%d", &M);

	printf("input i : ");
	scanf_s("%d", &i);
	printf("input j : ");
	scanf_s("%d", &j);

	int mask = ~0;

	for (int k = i-1; k < j; k++) {
		mask ^= 1 << k;
	}

	N &= mask;

	N += M << (i-1);

	printf("%d\n", N);

}