GitHub 자세히보기

Algorithm/Programmers

[프로그래머스] k진수에서 소수 개수 구하기 for JAVA

devdange 2022. 1. 19. 02:11

문제 바로가기

 

코딩테스트 연습 - k진수에서 소수 개수 구하기

문제 설명 양의 정수 n이 주어집니다. 이 숫자를 k진수로 바꿨을 때, 변환된 수 안에 아래 조건에 맞는 소수(Prime number)가 몇 개인지 알아보려 합니다. 0P0처럼 소수 양쪽에 0이 있는 경우 P0처럼 소

programmers.co.kr

 

구현 아이디어

  1. 입력받은 n을 k진수로 변환하는 과정이 필요
  2. P가 조건에 해당하는지 확인(P 사이에 0이 있을 수 없음)
    2-1. 0P0
    2-2. P0
    2-3. 0P
    2-4. P
  3. P가 소수인지 확인
  4. 조건에 맞으면 answer를 1씩 증가

변수 

sb : n을 k진수로 변환하는 과정에서 사용할 변수(StringBuilder)
change : k진수로 변환된 문자열 값
tmp : 변환된 수 안의 P(long 타입)

 

함수

is_prime(long num) : 매개변수 num이 소수인지 확인하여 T/F를 반환하는 함수 

 

 

문제풀이

  1. n을 k진수로 변환
    int a;while (n >= k) {
            sb.insert(0, n % k);
            n /= k;
        }
        sb.insert(0, n);
  2.  P가 `0P0`, `P0`, `0P`, `P` 조건에 해당하고 소수인지 확인
    long tmp = 0L; // 변환된 수 안의 P
            for (int i = 0; i < change.length(); i++) {
                // 0을 만나면 P가 소수인지 확인
                // 소수이면 answer에 1을 더해주고 P는 0으로 초기화
                if (change.charAt(i) == '0') {
                    if (tmp != 0L && is_prime(tmp)) {
                        answer++;
                    }
                    tmp = 0L;
                    // 0이 아니면 P에 값을 더함
                } else {
                    tmp = tmp * 10 + change.charAt(i) - '0';
                }
            }
            // for문을 돌고 난 후에는 '0P'가 존재할 수 있기 때문에 확인 필요
            if (tmp % 10 != 0L && is_prime(tmp))
                answer++;
  3. P가 소수인지 확인
    private static boolean is_prime(long num) {
            if (num == 1)
                return false;
            // 루트로 소수 구하기
            int max = (int) Math.sqrt(num);
            for (int i = 2; i <= max; i++) {
                if (num % i == 0)
                    return false;
            }
            return true;
        }​
  4. 결과 answer 출력

전체 Solution

class Solution {
	public static int solution(int n, int k) {
		int answer = 0;
		StringBuilder sb = new StringBuilder();
		// k진수로 변환
		while (n >= k) {
			sb.insert(0, n % k);
			n /= k;
		}
		sb.insert(0, n);
		// 변환된 값
		String change = sb.toString();
		long tmp = 0L; // 변환된 수 안의 P
		for (int i = 0; i < change.length(); i++) {
			// 0을 만나면 P가 소수인지 확인
			// 소수이면 answer에 1을 더해주고 P는 0으로 초기화
			if (change.charAt(i) == '0') {
				if (tmp != 0L && is_prime(tmp)) {
					answer++;
				}
				tmp = 0L;
				// 0이 아니면 P에 값을 더함
			} else {
				tmp = tmp * 10 + change.charAt(i) - '0';
			}
		}
		// for문을 돌고 난 후에는 '0P'가 존재할 수 있기 때문에 확인 필요
		if (tmp % 10 != 0L && is_prime(tmp))
			answer++;
		return answer;
	}

	// 소수 구하기
	private static boolean is_prime(long num) {
		if (num == 1)
			return false;
		// 루트로 소수 구하기
		int max = (int) Math.sqrt(num);
		for (int i = 2; i <= max; i++) {
			if (num % i == 0)
				return false;
		}
		return true;
	}
}

 

 

마치며

소수 구하는 방법은 다양하지만 시간초과를 방지하기 위해선 가장 효율적인 방식을 알아두고 있는 것이 좋을 것 같다. 이번 풀이에서 적용한 방법은 해당 숫자의 √N 까지 확인하는 것으로 약수의 중심을 구하는 방법이었다.O(√N)