티스토리 뷰

문제링크

📝 문제

두 문자열 sskip, 그리고 자연수 index가 주어질 때, 다음 규칙에 따라 문자열을 만들려 합니다. 암호의 규칙은 다음과 같습니다.

  • 문자열 s의 각 알파벳을 index만큼 뒤의 알파벳으로 바꿔줍니다.
  • index만큼의 뒤의 알파벳이 z를 넘어갈 경우 다시 a로 돌아갑니다.
  • skip에 있는 알파벳은 제외하고 건너뜁니다.

예를 들어 s = "aukks", skip = "wbqd", index = 5일 때, a에서 5만큼 뒤에 있는 알파벳은 f지만 [b, c, d, e, f]에서 'b'와 'd'는 skip에 포함되므로 세지 않습니다. 따라서 'b', 'd'를 제외하고 'a'에서 5만큼 뒤에 있는 알파벳은 [c, e, f, g, h] 순서에 의해 'h'가 됩니다. 나머지 "ukks" 또한 위 규칙대로 바꾸면 "appy"가 되며 결과는 "happy"가 됩니다.

두 문자열 sskip, 그리고 자연수 index가 매개변수로 주어질 때 위 규칙대로 s를 변환한 결과를 return하도록 solution 함수를 완성해주세요.


제한사항
  • 5 ≤ s의 길이 ≤ 50
  • 1 ≤ skip의 길이 ≤ 10
  • sskip은 알파벳 소문자로만 이루어져 있습니다.
    • skip에 포함되는 알파벳은 s에 포함되지 않습니다.
  • 1 ≤ index ≤ 20

입출력 예
s skip index result
"aukks" "wbqd" 5 "happy"

🔍 정답

class Solution {

    static int[] alphabet;

    public String solution(String s, String skip, int index) {
        String answer = "";

        char[] toCharSkip = skip.toCharArray();
        alphabet = new int[26];

        // skip에 포함되는 알파벳의 인덱스 값을 1로 바꾼다!
        for (int i = 0; i < skip.length(); i++) {
            alphabet[toCharSkip[i] - 97] = 1;
        }

        // move 메서드를 거쳐서 출력값에 담기
        char[] toCharInput = s.toCharArray();
        for (int i = 0; i < toCharInput.length; i++) {
            char output = (char) (move(toCharInput[i], index) + 97);
            answer += String.valueOf(output);
        }

        return answer;
    }

    public static int move(char ch, int index) {
        int idx = ch-97;

        /**
        * 기본적으로 index만큼 이동하되
        * alphabet[index] == 1이면 추가로 이동한다.
        * 그리고 idx가 z를 넘어가면 a로 이동!
        */
        while (index-- > 0) {
            idx++;
            if (idx >= alphabet.length) idx = idx - alphabet.length;
            if (alphabet[idx] == 1) {
                index++;
            }
        }
        return idx;
    }
}
  • 어떻게 구현해야 될지 고민이 정말 많았고 형변환을 이리저리 해보면서 많이 공부가 되었던 문제이다.
  • 기본적인 접근법은, 현재 자리(idx)에서 index만큼 이동을 하되 범위가 z를 넘어가면 a로 보내고, 이동한 곳이 int배열에서 1로 초기화된 (skip) 곳이면 추가로 이동하게 로직을 짰다.
  • skip값이 "az" 이고 index가 1인 경우, y에서 move 메서드를 시작한다고 가정하면 z를 거쳐서 a를 거쳐서 b를 출력해야 하는데 조건문을 잘못 작성하면 z를 거쳐서 a로 넘어가서 그대로 출력되는 경우도 있었다.

🔎 정답 (다른 사람 풀이)

class Solution {
    public String solution(String s, String skip, int index) {
        StringBuilder answer = new StringBuilder();

        for (char letter : s.toCharArray()) {
            char temp = letter;
            int idx = 0;
            while (idx < index) {
                temp = temp == 'z' ? 'a' : (char) (temp + 1);
                if (!skip.contains(String.valueOf(temp))) {
                    idx += 1;
                }
            }
            answer.append(temp);
        }

        return answer.toString();
    }
}
  • 이렇게 간단하게 풀어낸 걸 보고 놀라버렸다.
  • 형변환 문제라고 생각했는데 사실은 아니었던 것...
  • index만큼 이동을 해야 해서 int로 형변환 할 수밖에 없다고 생각을 했었고 그래서 String to char, char to int, int to char, char to String 이런식으로 계속 형변환 했어야 하는데 메모리 낭비였다 ㅠㅠ
  • 문자 + 1을 해서 문자 이동을 하는 것과 String.valueOf 로 문자를 바로 비교하는 것에서 차이가 났던 것 같다.
반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함