백준 - 회문인 수 11068번

greenTea·2024년 10월 4일

코드

import java.util.Scanner;
import java.util.stream.IntStream;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		IntStream.range(0, T).forEach(i -> radixIsPalindrome(sc.nextInt()));
	}

	private static void radixIsPalindrome(int num) {
		boolean isExist = IntStream.rangeClosed(2, 64)
								   .mapToObj(radix -> exchangeRadix(num, radix))
								   .anyMatch(Main::isPalindrome);
		System.out.println(isExist ? "1" : "0");
	}

	private static String exchangeRadix(int num, int radix) {
		StringBuilder sb = new StringBuilder();
		while (num > 0) {
			if (num % radix < 10) {
				sb.append(num % radix);
			} else {
				sb.append((char)(num % radix - 10 + 'A'));
			}
			num /= radix;
		}
		return sb.toString();
	}

	private static boolean isPalindrome(String str) {
		return IntStream.range(0, str.length() / 2).allMatch(i -> str.charAt(i) == str.charAt(str.length() - 1 - i));
	}
}

설명

  1. radixIsPalindrome메소드를 통해 각 2부터 64진법으로 진수를 변경하였을때 해당 isPalindrome로 회문 체크
  2. exchangeRadix를 통해 진법을 변화
  3. isPalindrome을 통해 회문인지 체크 맨 앞과 맨 뒤에서 부터 하나씩 이동하면서 같은지 체크하고 다르면 바로 return
  4. 회문이 하나라도 존재한다면 1을 출력 그 반대는 0을 출력

주의점

처음에는 Integer.toString(number,radix)를 통해서 진법을 변경하여 풀이를 하였습니다.
그러나 계속해서 통과를 하지 못하였고 이에 구글링을 통해 찾던 중 반례를 찾아주세요 ㅜㅜ - [백준 질문게시판]를 통해 무엇이 문제였는지 찾을 수 있었습니다.
Integer.toString(number,radix)의 내부 구현 코드를 들어가보면 아래와 같이 되어 있는 것을 볼 수 있습니다.

public static String toString(int i, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;

        /* Use the faster version */
        if (radix == 10) {
            return toString(i);
        }
        ...생략

radix가 MAX값을 넘어가면 그냥 radix를 10으로 변경하는 코드인데 확인해본 결과 Character.MAX_RADIX은 36으로 확인이 되었습니다.

코드를 확인함에 있어 내부 동작을 모른채로 사용하는 것에 반성하게 되는 계기가 된 것 같습니다.

출처
백준 - 회문인 수 11068번
반례를 찾아주세요 ㅜㅜ - [백준 질문게시판]

profile
greenTea입니다.

0개의 댓글