자바 알고리즘(백준)

숫자 N을 B 진법으로 나타내기

류정근 2024. 5. 1. 23:40

문제: 10진수 N을 B 진법으로 나타내는 코드를 만들어라.

 

과정: 문제를 보고 처음 든 생각은 2진법 말고는 기억이 잘 나지 않는다는 것 이였다.

정확히는 n진법의 원리에 대한 이해가 덜 잡혀 있었다. 막막했다. 문제에 접근하는 것 조차 힘들었다.

그 때 마침 같이 공부하던 분들이 N진법이란 무엇인가 원리를 이해하는데 도움을 주었다.(원호님 규리님 항상 감사합니다ㅠㅠ) 

16진법에서  f 다음 10이 된다는 것을 이해하는 것에는 꽤 오래걸렸지만 표로 정리를 하니 이해가 금방 가능했다.

표로 정리를 하다 보니 코드를 짜는 로직이 머릿속에 떠오르기 시작했다. 알고리즘 문제를 접하기 전 이였다면 원리를 알아도 쉽게 접근 하지 못하였을 텐데 얼마전 풀었던 알람 문제중 시간을 나타내는 방법이 떠오른 것이다.

시간 표현을 고민하다가 (시간 * 60 + 분) 즉 분으로 통일 한뒤 60을 나누어 주어 몫은 시간으로, 나머지는 분으로 정리하였던 방법에서 힌트를 얻었다. 결국 시간도 분으로 본다면 60진수인 것 아닌가?

그렇다면 (10진수인 숫자) N 에서 B^3 을 나눈다면 몫은 백의 자리 일 것이고 나머지에서 또 B^2을 나누면 몫은 십의 자리가 되고 나머지는 ....이런식으로 반복을 한다면 B진법으로 나타 낼 수 있다.

 

처음 떠오른 방법은 반복문 이였다.

while을 사용하여 계속 B^3,B^2순으로 나누어 가자.

그렇게 while 문으로 접근을 하던중 어차피 계속 if를 사용해서 N > B^3 , N > B^2 .... 인지 확인을 해야 한다는 것을 깨달았다.

그래서 그냥 while을 지우고 if를 사용해서 나누고 나머지 값을 임시 변수 temp를 만들어 저장하기로 했다.

그 결과문은 이러하다.

 

package practice.backjun.math;

import java.util.Scanner;

public class jinbeob {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 10진수를 B 진법으로 바꾸기

        int B = 7; //진법
        int n = 560; // 수
        
        
       int a = 0;  // 1의 자리
       int b = 0; // 10의 자리
       int c = 0;  // 100의 자리
       int d = 0; // 1000의 자리


            int temp = 0;
            int temp2 = 0;
            //1000의 자리
            if (n > ( B * B * B)) {
                d = n / ( B * B * B);
                temp = n % (B * B * B);
            } if (temp > ( B * B)) {
                c = temp / (B * B);
                temp2 = temp % (B * B);
            } if (temp2 > B) {
            b = temp2 / B;
            a = temp2 % B;
                System.out.println("1000의자리" + d + "    100의자리" + c + "     10의자리" + b + "     1의자리" + a);

        }

    }


    }

 

너무 뿌듯하게 결과는 한번에 성공적으로 나와 주었다.

하지만 아직 실력 부족으로 구현하지 못한 부분이 몇가지 있었다.

1. 자릿수를 직접 변수로 선언하여야만 한다 --> 내가 설정한 자릿수 보다 큰 결과 값은 얻을 수 없다.

2.조건 부분에서도 네제곱 초과는 상정되어 있지 않다.

 

1번 문제는 해결 방법이 쉽게 떠오르지 않았다.

2번 문제는 for 문을 통해 B를 계속 곱해주면 될거라는 추측은 있었지만 실제 코드로 작성하는데 막히는 부분이 많았다.

 

고민을 하며 검색을 하다가 같이 공부하던 분들이 경험이 많아 피드백을 부탁하였다.

 

코드에 대한 피드백

1.불피요한 변수가 많다. --> 임시변수 temp 가아닌 n에 직접 나머지를 대입하여도 된다. (코드를 run 하면 컴퓨터는 밑으로 쭉 읽어 나가기 때문)

2.자릿 수는 배열을 통해 만들 어라. --> 입력받는 변수에 따라 자릿수 추가가 가능해 진다.

3.Math.pow( a(밑), b(지수) ) 를 사용하면 제곱을 쉽게 계산 할 수있다. --> 새로 알게된 기능

 

피드 백 받은 사항들과 직접 많은 도움을 주신 팀원덕분에 (원하님 다시한번 감사드립니다ㅠㅠ)

새로운 코드를 깔끔하게 이해 할 수 있었다.

package practice.backjun.math;
public class jinbeopReview{
public static void main(String[] args) {
    // 진법 B, 10진수 N
    int B = 11; // 진법
    double N = 11; // 10진수의 값
    int max_exp = 0;
    while (Math.pow(B, max_exp) < N) {// B진법의 [B의 max_exp 승] 까지 존재하단걸 확인
        max_exp++;
    }

    int[] e자릿수 = new int[max_exp];


    for (int k = 0; k < max_exp - 1; k++) {
        if (N > Math.pow(B, max_exp - 1 - k)) {
            e자릿수[k] = (int) (N / Math.pow(B, max_exp - 1 - k));
            N = N % Math.pow(B, max_exp - 1 - k);
        }
    }
    
    for (int i = 0; i < max_exp; i++) {
        System.out.println( max_exp - i + "의 자리: " + e자릿수[i]);
    }

}
}

 

 

배열 사용, 반복문 , Math.pow 를 통해 이제 자릿 수의 제약 없이 결과값을 얻을 수 있었다.

코드 복습중 리뷰

 

다음날 복습을 하던 중 두가지 문제점을 발견 했다.

1의 자리를 대입받는 변수가 없다는 점 -> 제일 아래 빨간 박스를 통해 해결!

B = N 일때 자릿수가 넘어가지 않는다는점 -> N을 나누고, 크기를 비교할 때 <=, >= 등호를 통해 해결!!

 

몇시간을 고민한 문제였지만 전혀 시간이 아깝지 않을 만큼 많은 것을 배웠다.

피득해 주신 모든 분들께 감사합니다.

하지만 아직 10 = a , 11 = b, 12 = c , .... 이런식으로 나타낼 방법을 찾아야 한다는 것 ^^

'자바 알고리즘(백준)' 카테고리의 다른 글

별찍기 (하드버전)  (1) 2024.04.25
알고리즘 적응기(1)  (0) 2024.04.02