일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- CS지식
- 인터럽트핸들러
- it세계의 괴물들
- 파이썬
- AWS
- 2903
- 개발자
- transiant
- Java
- CPU의 구성요소
- 백엔드 면접지식
- hELLO 스킨
- 알고리즘
- HTTP
- 백준
- BOJ
- 공부
- LAMBDA
- 코딩테스트
- 자바
- 그림자 문제
- 카카오톡API
- Roy Fielding
- 빈 라인
- 개발공부
- 백엔드
- mac 코드 블럭
- 딩코딩코
- 비전공자
- 문자열
- Today
- Total
아직은 NULL NULL 합니다
[백준:2745/Python] 진법 변환 문제 본문
진법이란?
0부터 n개의 숫자를 사용하여 수를 표현하는 방법으로 0~(n-1)만큼 표현한다.
수를 표기하는 기수법의 하나로 임의의 숫자를 사용하여 수를 표현하는 방법이다.
문제 요약
B진법 수 N이 주어지면 이 수를 10진법으로 바꿔 출력하는 프로그램을 작성하는 문제이다.
예를 들어, 10진법을 넘어가게 되면 알파벳 대문자를 이용하는데
A : 10, B: 11, ... ,Z : 35
처럼 알파벳 대문자는 각각 위의 숫자를 의미하게 된다.
문제 풀이
먼저 내가 푼 풀이를 공유하자면, 아래와 같다.
import sys
n,b = sys.stdin.readline().split()
sum = 0
for i in range(len(n)) : # 0 ~ 문자열길이까지
if (n[(len(n)-1)-i].isdigit()) : # 숫자일경우 1의 자리부터
sum += int(n[(len(n)-1)-i]) * (int(b)**i)
else : # 문자일경우 -55
sum += (ord(n[(len(n)-1)-i])-55) * (int(b)**i)
print(sum)
여기서 핵심은 두 가지라고 생각했다.
1. B로 주어지는 진법을 어떻게 10진법으로 바꾸는지 (수학적 사고방식)
2. 문자열안에 숫자로 변환할 수 있는 문자가 있는지
3. 10진법을 넘어간 알파벳 대문자를 어떻게 확인하여 조건식을 짤 것인지
고등학교는 이과계열이었지만, 대학 전공은 수학과는 전혀 무관한 곳을 졸업한 비전공자로서
이처럼 간단한 진법 변환조차, 기억이 안 날 때가 있다.
그래서 내게 1번 문제는 가장 큰 핵심이었다.
나와 같이 수학을 놓은지 오래된 개발자 취준생들에게 도움이 되었으면 좋겠다.
1번 문제 접근 방식
문제의 테스트 케이스로 주어진 아래 사진에서 36 진법으로 표현된 'ZZZZZ' 문자열이 있다.
36 진법에서 10진법으로 바꾸는 방식은 간단하다.
어렵게 36진법 먼저 생각하기보다 10진법의 원리를 파악하면 된다.
350이라는 10진법으로 이루어진 숫자가 있다고 가정을 해보자.
그럼 이것은 10진법으로 어떻게 표현이 되는가?
(여기서 n의 승을 표현하려면 파이썬문법으로 ** 를 사용하면 된다.)
3 * (10의 2승) = 3*(10**2) = 3*100 = 300
5 * (10의 1승) = 5*(10**1) = 5*10 = 50
0 * (10의 0승) = 0*(10**0) = 0*1 = 0
이다.
그렇다면 36 진법으로 이루어진 'ZZZZZ' 문자열을 10진법으로 변환한다면 어떻게 될까?
똑같다.
이 문제에서의 Z 는 위에서 언급했듯이 35 숫자로 표현할 수 있다.
그렇다면,
35 * (36의 4승) = 35 * (36**4)
35 * (36의 3승) = 35 * (36**3)
35 * (36의 2승) = 35 * (36**2)
35 * (36의 1승) = 35 * (36**1)
35 * (36의 0승) = 35 * (36**0)
인 것이다.
위의 모든 계산을 다 더하게 되면 60466175로 10진법 변환이 끝난다.
이로써 1번 문제는 해결했다.
2번 문제 접근 방식
이 문제는 스스로 파이썬 문법이 부족하다는 것을 인지하고 검색을 통해 알게 된 함수이다.
isdigit( ) : 어떤 문자열이 숫자의 형태면 True를 반환한다.
이 함수가 위에서 직접 사용된 함수이다.
'ZZZZZ' 문자열은 문자 하나하나가 숫자의 형태가 아니기때문에 False를 반환한다.
하지만, 11진수로 표현된 '10A' 가 입력값으로 주어진다면
'10A' 문자열을 반복문 돌려서 문자 하나하나를 숫자로 변환가능한지 비교한다면
A는 False 를 반환하고
1과 0 은 True 를 반환하게 된다.
이것 외에도 이와 비슷한 함수 종류를 추가적으로 작성하자면,
isdecimal( ) : 어떤 문자열이 int 형으로 변환이 가능하면 True
isnumeric( ) : 숫자값 표현에 해당하는 문자열이면 True
isalpha( ) : 문자열이 알파벳으로만 구성되어 있다면 True, 공백 또는 숫자의 형태로 변환가능한 문자가 포함되어 있다면 False.
등등 여러가지가 존재한다.
나는 간단하게 작성해 보았다.
3번 문제 접근 방식
이 문제는 ord( ) 라는 파이썬 함수를 이용하여 문제를 해결할 수 있었다.
원래는 알파벳이 담긴 리스트를 작성하여 index로 접근해서 문제를 풀려고 했지만
A부터 Z까지 적는 것은 생각보다 귀찮다고 생각이 들었다.
그래서 알파벳을 유니코드 숫자값으로 변환해주는 ord( ) 함수를 이용하여
A의 유니코드 숫자값이 65 인 것을 확인하였고 문제에서의 A는 10을 가진다는 것과 비교하여
65 - 55 를 하면 10 이 된다는 것을 알 수 있었다.
그렇게 3가지의 핵심문제를 해결하고 맞출 수 있었다.
그런데 이보다 더 쉽게 푼 방식은 없을까 해서 찾아보니 정말 간단한 문법을 놓쳤다는 것을 알 수 있었다.
다른 문제 풀이 방식
n,b = input().split()
print(int(n, int(b)))
이것을 보고 정말 기초가 탄탄해야 하는구나라는 것을 새삼 느꼈다.
파이썬의 Int 함수는 임의의 진법 수를 10진법으로 변환하는 데 사용할 수 있다는 것이다.
즉, int('ZZZZZ', 36) 형식은 36진법으로 이루어진 'ZZZZZ'를 10진법으로 변환한다는 의미를 갖고 있다.
이러한 기초가 중심이어야 하는 문제를 기억해야겠구나 싶어서 기록해본다.
'Algorithm > BOJ' 카테고리의 다른 글
[백준 : JAVA] 1439. 뒤집기 (2) | 2025.03.08 |
---|---|
[백준:2903/Python] 중앙 이동 알고리즘 (0) | 2023.11.02 |
[백준:15829/Python] Hashing 문제 (0) | 2023.09.27 |