제목 : 진법 변환
문제
B 진법 수 N 이 주어진다.
이 수를 10 진법으로 바꿔 출력하는 프로그램을 작성하시오.
10 진법을 넘어가는 진법은 숫자로 표시할 수 없는 자리가 있다.
이런 경우에는 다음과 같이 알파벳 대문자를 사용한다.
A: 10B: 11- ...
F: 15- ...
Y: 34Z: 35
입력
첫째 줄에 N 과 B 가 주어진다. (2 <= B <= 36)
B 진법 수 N 을 10 진법으로 바꾸면, 항상 10억보다 작거나 같다.
출력
첫째 줄 B 진법 수 N 을 10 진법으로 출력한다.
예제 입력 1
ZZZZZ 36
예제 출력 1
60466175
어느 언어 프로그램에나 진법을 쉽게 변환할 수 있는 메서드나 편의 클래스는 존재한다.
하지만, 하나의 언어에 대한 숙련도를 보는 것이 아니라,
일반 수학을 다룸으로서 뇌를 "말랑" 하게 만드는 데 초점이 있다고 생각한다.
그렇다면, "진법" 이란 무엇인가?
우리는 당연하게도 "10진법" 을 사용하고 있다.
그리고, 컴퓨터는 트랜지스터의 ON OFF 의 개념으로, "2진법"을 사용한다.
따라서, "진법" 이란, 우리가 수를 바라보는 "관점" 에 해당한다.
다시 문제로 돌아와서, 하나의 줄에 모든 입력이 주어진다.
첫 번째 단어로 주어지는 것은 특정 "진법" 으로 변환 된 결과이다.
두 번째 단어로 주어지는 것은 변환시킨 "진법" 숫자에 해당한다.
그렇다면, 주어진 예제 입력 을 예시로 들어, 테이블로 실제 값을 알아보자.
| 5 | 4 | 3 | 2 | 1 | 자리수 |
|---|---|---|---|---|---|
| Z | Z | Z | Z | Z | 수 |
| 35 | 35 | 35 | 35 | 35 | 십진수 |
| 36 ^ 4 | 36 ^ 3 | 36 ^ 2 | 36 ^ 1 | 36 ^ 0 | 해당 자리수가 의미하는 실제 값 |
| 35 x (36^4) | 35 x (36^3) | 35 x (36^2) | 35 x (36^1) | 35 x (1) | 십진수로 변환되는 계산식 |
| ...... + | ...... + | ...... + | ...... + | ...... = | 60,466,175 |
결과적으로, 각 자리수가 의미하는 십진수의 값을 "각각" 구하고 나서, 이를 전부 더해주면,
해당 값이 "십진수" 로 표현되었을 때의 값이 나오게 된다.
그렇다면, 우리는 여기서 2 가지 방식으로 문제에 접근 할 수 있다.
- 가장 앞 부분부터 접근한다
- 가장 뒤 부분부터 접근한다.
나는 처음 이 문제를 접했을 때, 가장 뒤 부분부터 접근하는 방식을 채택했었다.
이유는 각 자리수가 곱해야 하는 수 자체는 지속적으로 "진법" 만큼 곱해진다.
따라서, 문자열을 뒤에서부터 차근히 제거하며 계산했다.
그러나, 실제로 테이블로 펼쳐 본 시각으로서, 앞에서 해도 편리하겠다는 생각이 든다.
Answer 1 - 문자열 맨 뒤에서부터 계산
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 10 진수로 변환해야 할 수
String numStr = st.nextToken();
// 현재 진법
int orient = Integer.parseInt(st.nextToken());
int result = 0;
int pow = numStr.length() - 1;
for(int i = 0; i < numStr.length(); i++) {
char ch = numStr.charAt(i);
int realNum = realNum(ch);
realNum *= pow(orient, pow);
pow--;
result += realNum;
}
System.out.println(result);
}
static int realNum(char ch){
String str = "";
if('0' <= ch && ch <= '9'){
str += ch;
return Integer.parseInt(str);
} else {
return (ch - 'A') + 10;
}
}
static int pow(int orient, int repeat) {
int result = 1;
while(repeat > 0) {
result *= orient;
repeat--;
}
return result;
}
}
Java 에서는 진법 변환을 위한 메서드가 존재하며,
Math.pow 를 통한 계산도 존재한다.
하지만, 이를 세부화하여 관심사항을 분리하며 구현한다면
위와 같이 realNum, pow 메서드를 구현 할 수 있다.
맨 앞에서부터 계산하기 때문에, 현재 위치에 따른 곱수는 처음부터 계산해야 한다.
(현재 알파벳의 실제 수 x 현재 위치에 의한 곱수) + ( .... ) + ... == 결과
Answer 2 - 문자열 맨 앞에서부터 계산
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
String strNum = st.nextToken();
int orient = Integer.parseInt(st.nextToken());
int result = 0;
int powNum = 0;
for(int i = strNum.length() - 1; i >= 0; i--) {
char ch = strNum.charAt(i);
int realNum = parseInt(ch);
realNum *= pow(orient, powNum);
powNum++;
result += realNum;
}
System.out.println(result);
}
static int parseInt(char ch) {
String str = "";
if('0' <= ch && ch <= '9') {
str += ch;
return Integer.parseInt(str);
} else {
return (ch - 'A') + 10;
}
}
static int pow(int orient, int num) {
int result = 1;
while(num > 0) {
result *= orient;
num--;
}
return result;
}
}'백준-단계별로 풀어보기 > 8-일반 수학 1' 카테고리의 다른 글
| 백준 1193 Java - 분수찾기 (0) | 2025.02.11 |
|---|---|
| 백준 2903 Java - 중앙 이동 알고리즘 (0) | 2025.02.08 |