구현 문제이다. 근데 그냥 빡 하고 부딛히는 구현이 아닌, 수학적인 방법론을 잘 찾아서 구현을 해야 하는 문제였다.
진법 변환 자체는 크게 다를게 없다. 진법의 밑 수로 계속해서 나머지 연산을 해주고 그 나머지들을 역순으로 출력하면 된다.
문제는 음수 진법의 경우.
무조건 나머지는 0이 되어야 한다. 따라서 나머지 연산을 재정의 해야한다.
a % abs(b) = a % abs(b) (결과가 양수일 경우), a % abs(b) + abs(b)(결과가 음수일 경우, 나누는 수의 절대값을 더해 보수로 만들어준다)
이렇게 재정의된 나머지 연산을 사용해, 나누기 연산도 재정의해준다.
a / b = (a - a % b) / b -> 구한 나머지를 뺀 수를 나눠준다.
이렇게 구현을 해 두면, 음수 진법은 잘 구할 수 있지만 양수 진법일 때 음수 처리 등에 문제가 생긴다. 따라서 양수 진법일 때는 아예 변환할 수를 절대값으로 처리해두고, 원래 부호에 따라 맨 앞에 음수 기호를 추가해 출력해준다.
#include <iostream>
#include <vector>
#include <math.h>
int base_N;
class INT {
int data;
public:
INT(int input){
data = input;
}
void absolutize_data()
{
data = abs(data);
}
INT operator/ (INT &other)
{
return (INT((data - (*this % other)) / other.data));
}
int operator% (INT &other)
{
int r = data % abs(other.data);
if (r < 0)
r += abs(other.data);
return (r);
}
INT operator= (int other)
{
data = other;
return *this;
}
bool operator== (int other)
{
return (data == other);
}
bool operator< (int other)
{
return (data < other);
}
bool operator> (int other)
{
return (data > other);
}
bool operator!= (int other)
{
return (data != other);
}
friend std::istream& operator>> (std::istream &is, INT &p);
};
std::istream& operator>> (std::istream &is, INT &p)
{
is >> p.data;
return is;
}
int main()
{
std::vector<int> change_digit;
INT x(0);
INT base(0);
std::cin >> x >> base_N;
if (x==0)
std::cout << 0;
base = base_N;
bool isNeg = (base > 0 && x < 0);
if (base > 0)
x.absolutize_data();
while (x != 0){
change_digit.push_back(x % base);
x = x / base;
}
if (isNeg)
std::cout << '-';
for (int i = change_digit.size()-1 ; i >= 0; i--)
{
std::cout << change_digit[i];
}
}
구현하면서 연산자 오버라이딩 연습을 좀 해봤다. 나눗셈과 나머지 연산을 그대로 사용하고 싶어서 따로 INT 클래스를 만들어서 구현해보았다. 조금 더 유려하게 작성 할 수 있을 것 같은데, 나중에 한번 리팩토링 해봐야겠다.
오늘도 평온한 하루가 되길. 슨민.
'짜잘한 기록' 카테고리의 다른 글
백준 1981 배열에서 이동 (0) | 2021.11.18 |
---|---|
백준 2470 두 용액 (0) | 2021.11.17 |
백준 12904 A와 B (0) | 2021.11.09 |
백준 2636 치즈 (0) | 2021.11.08 |
[문을 편하게 열고 싶다] UID changable tag에 카드 복사하기(완) (0) | 2021.11.04 |