2745번: 진법 변환
문제:
B진법 수 N이 주어진다. 이 수를 10진법으로 바꿔 출력하는 프로그램을 작성하시오.
10진법을 넘어가는 진법은 숫자로 표시할 수 없는 자리가 있다. 이런 경우에는 다음과 같이 알파벳 대문자를 사용한다.
A: 10, B: 11, ..., F: 15, ..., Y: 34, Z: 35
입력:
첫째 줄에 N과 B가 주어진다. (2 ≤ B ≤ 36)
B진법 수 N을 10진법으로 바꾸면, 항상 10억보다 작거나 같다.
풀이:
- 이 문제는 #11005: 진법 변환 2을 반대로 구현 시키는 문제이다. 비유하자면 5+2가 7인것을 구하는 프로그램을 구현 하였으면 이제 7-5가 2가 나오는 프로그램을 구현 하는 문제여서 개념을 인지하고 있으면 구현 하는 것은 어렵지 않다. 따라서 이 문제를 풀기 전에 #11005: 진법 변환 2를 확인하고 n진법으로 변환하는 방법을 이해하고 오기 바란다.
- 진법 변환 2 문제와 마찬가지로 11진법 이상인 경우 즉, 알파벳을 쓰는 경우와 안쓰는 경우를 나누어 준다. 알파벳이면 연산을 다르게 해줘야 되기 때문이다. 우선, 자리수마다 접근하여 계산을 해주어야 되므로 문자열로 값을 받아준 뒤 앞에서부터 한자리씩 접근한다.
- 여기서 사용하는 for(int number: numbers)는 오늘 대학에서 배운 것인데 c++ 11버전부터 추가 된 기능이며 python의 (for i in array)와 같은 역할을 해준다. 이걸 사용하면 인덱스로 값을 호출하는 것이 아닌 배열 안에 있는 값을 하나씩 앞에서부터 접근을 하게 된다.
- #11005: 진법 변환 2에서 봐서 알겠지만 n진법으로 변환 된 수는 모든 자리수가 나누기 연산 후의 나머지 라는 것을 알 것이다. 앞에서부터 제일 마지막 연산의 나머지이므로 제일 앞에 값에서부터 연산을 시작하는 것이다.
- 우선, 알파벳인 경우에는 11진법 이상이므로 ASCII 코드를 이용한 연산으로 10진법의 수로 나머지를 변환해준다. 숫자인 경우는 -’0’연산을 통해 int값을 반환하도록 한다.
- 우리가 구해야 되는 값은 나누기 전에 어떤 수를 나눴는지를 알아야 된다. 나누기 전의 수 = 나눈수n(진법)+나머지이다. 나머지는 위에서 말했다시피 이미 배열에 저장 되어 있고 나눈 수를 구해야 되는데 이 나눈 수 제일 마지막에는 무조건 0이므로 우리는 거꾸로 올라가므로 제일 처음에 0으로 초기화하면 된다. 그래서 아래 코드를 보면 answer를 처음에 0으로 초기화 하였다. 그렇게 되면 나누기 전의 수 = 0n+나머지이고 나누기 전전의 수 = 나누기 전의 수*n+나머지이므로 숫자의 길이만큼 연산을 반복 해주면 된다.
🧐 잘 이해가 안된다면 아무 수를 정한 뒤 몇진법으로 바꿀지 정한 뒤 정한수 = n(진법)*(정한수/n)(결과 값이 소수인 경우 반내림)+나머지를 적어서 n진법으로 바꾼 뒤 거꾸로 어떻게 해야 다시 처음 정한 값으로 갈 수 있을 지 생각해보면 쉽게 이해가 될 것이다.
코드:
#include <iostream>
using namespace std;
int main(){
string numbers;
int n, answer=0;
//입력
cin >> numbers >> n;
//N진법의 수 10진법으로 변환
for(int number: numbers){
//알파벳인 경우(11진법 이상인 경우)
if(number >= 'A' && number <= 'Z') answer = answer*n+(number-'A'+10);
//숫자인 경우(10진법 이하인 경우)
else if(number >= '0' && number <= '9') answer = answer*n+(number-'0');
}
//출력
cout << answer;
}