[프로그래머스 JAVA] 모음사전

2024. 5. 12. 20:56프로그래머스

[프로그래머스] 모음사전 : https://school.programmers.co.kr/learn/courses/30/lessons/84512
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제 조건 정리


입력 / 출력

 


문제를 풀기 전

 

  1. 완전탐색 문제지만 규칙을 찾을 수 있다고 생각함.
  2. 각 자릿수에는 NULL, "A", "E", "I", "O", "U" 가 들어갈 수 있음 -> 6진수와 비슷하게 취급하고 싶음
  3. 입력값을 "AAAAA" 와 비교한다면, 논리적으로 쉽게 풀이할 수 있을 것이라고 생각함.
  4. 아래 표에 따라서, 입력값을 숫자로 변환한 것과 11111 을 비교하는 것으로 가정함.
  5. 따라서 입력값이 "EAEAE" 라면 10101 만큼의 차이에 5를 더한 값을 정답으로 반환함.
    5를 더한 이유 : NULL NULL NULL NULL NULL (00000) 과 비교한 것이 아니라 AAAAA(11111) 과 비교했으므로.
  6. 혹시 입력값이 "EAE" 라면 2를 빌린다고 가정함,
    "EAEAA" 와 "AAAAA"와 비교하여 10100 만큼의 차이에 5를 더한 값에 빌린 2를 뺀 값을 정답으로 반환함.
최상위 자릿수       최하위 자릿수
이전 자릿수가 5번 증가 후
1 증가 -> 변경
이전 자릿수가 5번 증가 후
1 증가 -> 변경 
이전 자릿수가 5번 증가 후
1 증가 -> 변경
이전 자릿수가 5번 증가 후
1 증가 -> 변경
1 증가 -> 변경
(156 * 5) + 1 (31 * 5) + 1 (6 * 5) + 1 (1 * 5) + 1 1
NULL 0
"A" 1
"E" 2
"I" 3
"O" 4
"U" 5

 


코드

 

package programmers;

public class 모음사전 {

    static class Solution {

        public static void main(String[] args) {
            System.out.println(solution("IE"));
        }

        public static int solution(String word) {
            int answer = 0;

            // 입력값과 AAAAA와의 차이를 저장하는 변수
            int diffWithAAAAA = 0;

            // 입력값의 자릿수만큼 알파벳을 숫자로 변환
            for (int i = 0; i < word.length(); i++) {
                // 다음 자릿수로 변경 (i = 0 제외)
                diffWithAAAAA *= 10;

                switch (word.charAt(i)) {
                    case 'A' -> {
                        diffWithAAAAA += 0;
                    }
                    case 'E' -> {
                        diffWithAAAAA += 1;
                    }
                    case 'I' -> {
                        diffWithAAAAA += 2;
                    }
                    case 'O' -> {
                        diffWithAAAAA += 3;
                    }
                    case 'U' -> {
                        diffWithAAAAA += 4;
                    }
                }
            }

            // 입력값의 자릿수가 5자리가 아니라면 A로 채운다고 가정 (빌림)
            for (int i = 0; i < 5 - word.length(); i++) {
                diffWithAAAAA *= 10;
            }

            // 6진수의 개념으로 풀이
            // 특정한 자릿수만 변경되고, 나머지가 그대로 유지되기 위한 값을 계산함.
            // 1, 6, 31, 156, 781
            int[] digits = new int[5];
            digits[0] = 1;
            for (int i = 1; i < 5; i++) {
                digits[i] = digits[i - 1] * 5 + 1;
            }

            // 계산된 각 자릿수의 차이가 어느정도인지 digits를 이용해 정답 계산
            for (int i = 0; i < 5; i++) {
                int now = diffWithAAAAA % 10;
                answer += now * digits[i];
                diffWithAAAAA /= 10;
            }

            // 정답 : 계산된 차이 + 5(AAAAA(5)와 비교했으므로) - 빌린 값
            // word.length = (5 - 빌린 값)
            return answer + word.length();
        }
    }
}

 


문제를 풀고 난 후

 

문제를 완전탐색으로 풀지 않고 일반화해서 풀었으나, 이를 설명하려고 하니 이상한 개념이 많이 들어간 것 같아서 오히려 이해하기 어려울 것 같다.

 

결론적으로는 특정 자릿수의 변경이 몇 번의 단어 변경을 필요로 했는지를 찾아내야하는 문제라고 생각함!