본문 바로가기

컴퓨터/알고스팟 알고리즘

알고스팟 알고리즘: ENDIANS [C++]

문제 출처: algospot.com/judge/problem/read/ENDIANS

 

algospot.com :: ENDIANS

Endians 문제 정보 문제 The two island nations Lilliput and Blefuscu are severe rivals. They dislike each other a lot, and the most important reason was that they break open boiled eggs in different ways. People from Lilliput are called little-endians

algospot.com

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. 느낀 점

비트를 잘 다루어 볼 기회가 없었는데 이번 문제를 통해 비트를 다루는 경험을 했는데 많이 어색하지만 나름 좋은 경험이었다.