# 문제
B진법 수 N이 주어진다. 이 수를 10진법으로 바꿔 출력하는 프로그램을 작성하시오.
# 풀이
진법 변환은 알아두면 어디든 쓸모가 있는 것 같다.
우선 코드의 로직을 이해하기 위해 직접 진법 변환을 해보자.
5진법 수인 79152를 10진법으로 변환하는 과정은 다음과 같고,
3진법 수인 9735를 10진법으로 변환하는 과정은 다음과 같다.
n진법의 경우에도 이와 동일하게 해결하면 된다는 걸 기억하고 코드로 넘어가면 충분히 해결할 수 있다.
이해했다면 바로 정답 소스코드 확인!
#include <iostream>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); // 두 표준 입출력 동기화 해제
int b;
int res = 0;
string n;
cin >> n >> b;
for (int i = 0; i < n.length(); i++) {
if ('0' <= n[i] && n[i] <= '9') res = res * b + (n[i] - '0');
else res = res * b + (n[i] - 'A' + 10);
}
cout << res;
return 0;
}
이번에는 변수 선언 시 n을 주의해야 한다.
문제에서 제시했듯 10진법을 넘어가는 진법의 경우 알파벳이 입력될 수 있기 때문에, int형이 아닌 string을 사용!
for (int i = 0; i < n.length(); i++) {
if ('0' <= n[i] && n[i] <= '9') res = res * b + (n[i] - '0');
else res = res * b + (n[i] - 'A' + 10);
}
string을 사용해 숫자와 알파벳을 입력받기 때문에, int형로 변환해 계산할 필요가 있다.
매번 사용하는 아스키 코드값을 이용해 이를 처리해준다.
if문에서는 0-9까지의 숫자를, else문에서는 A-Z를 통해 입력되는 10-35를 계산해주면 끝!
➕ 원래 위의 for문 코드를 pow()를 사용했다가 고쳤는데 그 이유는 아래와 같다.
int len = n.length();
for(int i=0; i<len; i++){
if('0' <= n[i] && n[i] <= '9') tmp = n[i] - '0';
else tmp = n[i] - 'A' + 10;
res += tmp * pow(b, len - i - 1);
}
이렇게 코드를 작성해도 테스트 케이스 처리에는 문제가 없는지 정답 처리된다.
하지만 위에서 직접 진법 계산했던 예시를 넣어보면, 79152(5)는 10진법 변환 시 5552가 나와야 하지만 5551이 출력된다.
이는 pow() 함수가 부동소수점 연산을 수행해 정확한 정수 연산을 보장하지 않을 수 있기 때문이다. 우리는 현재 정수 계산에 관한 문제를 풀고 있으므로 pow() 함수 대신 반복문을 사용해 해당 문제를 피해가기로 하자.
'백준 > C++' 카테고리의 다른 글
[백준] 2720번: 세탁소 사장 동혁 | C++ 풀이 (0) | 2023.05.31 |
---|---|
[백준] 11005번: 진법 변환 2 | C++ 풀이 (0) | 2023.05.30 |
[백준] 2563번: 색종이 | C++ 풀이 (2) | 2023.05.28 |
[백준] 10798번: 세로 읽기 | C++ 풀이 (0) | 2023.05.27 |
[백준] 25206번: 너의 평점은 | C++ 풀이 (0) | 2023.05.26 |