문제 출처: algospot.com/judge/problem/read/ENDIANS
1. 코드
#include <iostream>
using namespace std;
class Mask {
unsigned int arr[4];
public:
Mask() //Mask 연산을 위한 비트 생성
{
arr[3] = 255;
for (int i = 2; i >= 0; i--)
arr[i] = arr[i + 1] << 8;
}
unsigned int conversion(unsigned int temp) //리틀엔디안과 빅엔디안 변환
{
unsigned int result[4];
result[3] = temp & arr[3]; //mask 연산 후
result[3] = result[3] << 24; //변환 위치로 이동
result[2] = temp & arr[2];
result[2] = result[2] << 8;
result[1] = temp & arr[1];
result[1] = result[1] >> 8;
result[0] = temp & arr[0];
result[0] = result[0] >> 24;
temp = 0;
for (int i = 0; i < 4; i++) //선택적 세트 연산 OR
temp |= result[i];
return temp;
}
};
int main(void)
{
int c;
cin >> c; //입력 횟수
while (c--) //입력 횟수만큼 반복
{
unsigned int n;
cin >> n;
Mask a;
cout << a.conversion(n) << endl;
}
}
(실행)
2. 풀이
문제가 영어되어 있어서 먼저 문제에서 요구하는 것은 엔디안(Endianness)의 개념 중 빅 엔디언(Big-endian)과 리틀 엔디언(Little-endian)에 대해서 빅 엔디언을 입력하면 리틀 엔디엔으로 변환시켜주고 리틀 엔디언을 입력하면 빅 엔디엔으로 변환하여 출력하라는 것이다.
간단하게 빅 엔디엔과 리틀 엔디언은 서로 상반되는 관계라 변환하는 방법은 한가지이다.
00000001 00000011 00000111 00001111를 입력하게 되면 00001111 00000111 00000011 00000001으로 변환이 된다. 그냥 단순한 자리 이동이라고 생각하면 편하다. 1→4, 2→3, 3→2, 4→1로 이동하게 된다. 그리고 문제에서 부호가 없는 32비트라고 명시하여 unsigned int형을 사용하여 비트연산을 해주면 쉽게 해결할 수 있다.
int c;
cin >> c; //입력 횟수
먼저 입력 횟수를 입력한다.
while (c--) //입력 횟수만큼 반복
{
unsigned int n;
cin >> n;
Mask a;
cout << a.conversion(n) << endl;
}
그리고 입력한 횟수만큼 반복해주는데 변환시켜줄 수를 입력한 뒤 객체 a를 생성하고 변환시킨 값을 출력해준다.
class Mask {
unsigned int arr[4];
public:
Mask() //Mask 연산을 위한 비트 생성
{
arr[3] = 255;
for (int i = 2; i >= 0; i--)
arr[i] = arr[i + 1] << 8;
}
그리고 Masking 연산(AND 연산)을 진행하기 위해 8비트를 기준으로 구역을 나누어 11111111로 만들어준다.
unsigned int conversion(unsigned int temp) //리틀엔디안과 빅엔디안 변환
{
unsigned int result[4];
result[3] = temp & arr[3]; //mask 연산 후
result[3] = result[3] << 24; //변환 위치로 이동
result[2] = temp & arr[2];
result[2] = result[2] << 8;
result[1] = temp & arr[1];
result[1] = result[1] >> 8;
result[0] = temp & arr[0];
result[0] = result[0] >> 24;
temp = 0;
for (int i = 0; i < 4; i++) //선택적 세트 연산 OR
temp |= result[i];
return temp;
}
};
변환시켜줄 값을 매개변수로 전달 받고 각 구역마다 따로 저장하기 위해 배열을 생성하고 masking 연산(AND 연산)을 해준 뒤 변환된 위치에 시프트 연산자를 통해 비트를 옮겨준다. 그리고 temp에 값을 0으로 만들고 반복문을 통해 변환 결과들을 or 연산자인 |를 통해 선택적 세트 연산을 해준다. 그리고 temp를 반환하면 변환된 결과로서 반환된다.
3. 느낀 점
비트를 잘 다루어 볼 기회가 없었는데 이번 문제를 통해 비트를 다루는 경험을 했는데 많이 어색하지만 나름 좋은 경험이었다.
'컴퓨터 > 알고스팟 알고리즘' 카테고리의 다른 글
알고스팟: LECTURE [C++] (0) | 2021.05.05 |
---|---|
알고스팟 알고리즘: DRAWRECT [C++] (0) | 2021.05.04 |
알고스팟 알고리즘: MERCY [C++] (0) | 2021.05.02 |
알고스팟(Algospot): 피크닉(PICNIC) [C++] (0) | 2020.11.17 |
알고스팟(algospot): 보글 게임(BOGGLE) [C++] (0) | 2020.11.11 |