ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [8일차](문제 번호 : 11005, 진법 변환 2) 도전 -2
    백준 문제 풀이 2023. 7. 27. 10:13

    1. 오류 이유

    저번 풀이에서 NameError가 발생했었다.

    이는 주로 변수 선언이 안된 상태에서 그 변수를 사용했을 때, 발생한다고 했다.

     

    N, B = map(int, input().split())
    for i in range(30):
        if N <= B**i:
            M = i
            break

    그리고 추정끝에, N = 1000000000 (최댓값) B =2 를 넣었을 때, NameError 가 발생했다.

    그 이유는 range(30)이 30을 포함하지 않기 때문에 i는 최대 29이고, 2^29은 약 5억이기때문에,

    5억 이상의 수들을 2진법으로 표현할 때, 오류가 발생했던 것이다.

    따라서 range(31)로 수정했다.


     

    또한, N = 1 or 0 일 때의 계산도 간편하게 하기 위해 아래의 식을 도입했다.

    BBase = []
    if M != 0:
        for i in range(M)[::-1]:
            for j in range(37):
                if N - j*B**i < 0:
                    BBase.append(j-1)
                    N -= (j-1)*B**(i)
                    break
    elif N == 1:
        BBase.append(1)
    else:
        BBase.append(0)

    새로 추가된건 elif 부분부터이다. M = 0 이라면, N = 1or0 이기 때문이다.

     

    그런데..


    2. 새로운 문제

    채점 결과.. 오류는 발생하지 않았지만, 계산 결과가 틀렸다.

    어딘가 논리적 결함이 있었다.

    먼저, 찾아낸 if N - j*B**i < 0 조건 식에서, ==0 일 때의 상황도 고려했어야했다.

    즉, 아래의 식을 추가로 삽입하였다.

    elif N - j*B**i == 0:
                    BBase.append(j)
                    for k in range(i):
                       BBase.append(0)
                    N=1000000000000
                    break

    N을 10억을 훨씬 초과하는 큰 수로써 바꾸는 이유는 만약 == 0 상황에서는

    B진법으로 바꿀 때, 재귀의 식을 고려하지않고, 남은 자리는 0으로 매꾸어 작성하면 되는 것이기 때문이다.

    (즉, if문을 더 이상 성립시켜 재귀식을 성립하지않게 하려고)

    다음으로 range의 범위도 아래와 같이 바꾸었다.

    for i in range(0,M+1)[::-1]:

     

    다음으로, 위의 range 범위를 바꾸었다보니, 첫자리가 0이 되어버렸다.

    B진법수로 바꾸었을 때, 일반적인 정수(0을 제외)는 맨 앞자리가 0이 되면 안되므로,

    아래의 식을 추가하여 앞자리의 0을 제거하였다.

    while BBase[0] == '0' and len(BBase) != 1:
        BBase = BBase.lstrip('0')

    3. 개선 방안

    맞힌 사람들의 정답 코드를 쓱 보니, int() 함수에 이러한 진법 변환 기능은 없는 것 같고,

    나보다 훨씬 깔끔한 논리로써 코드를 작성하였다.

     

    예를 들어 N = 23*36^3 + 18*36^2 + 35*36^1 + 35*36^0 = 139040 , B = 36 이라고 하면,

    N%B = 35이다.(진법수의 마지막 자리)

    N//B = 23*36^3 + 18*36^2 + 35*36^1 이다.

    위의 값을 N으로 지정하고 계속 반복하면 된다.

     

    나도 처음에는 이런 논리로 생각했었는데, 왜인지 모르겠지만.. 포기했었다.

    좀 더 해볼껄 그랬다.

     

     

    개인사정으로 글을 며칠간 못올렸다. 이로 인해 학교 행사에는 제대로 참여하지 못했지만,

    오늘 추가적으로 더 풀어야겠다는 생각이 든다.

Designed by Tistory.