프로그래머스_둘만의 암호

LeeYulhee·2023년 8월 10일
0

💻 문제 출처 : 프로그래머스_둘만의 암호

👉 내가 작성한 답


import java.util.*;

class Solution {
    public String solution(String s, String skip, int index) {

		// 정답을 만들기 위한 StringBuilder 생성
        StringBuilder sb = new StringBuilder();

        // ArrayList로 skip 글자들을 빼고 저장할 List 생성
        List<Character> exceptSkipChar = new ArrayList<>();

        // skip 글자들을 제외한 배열을 만듦
        for(int i = 0; i < 26; i++) {
            char alphabet = (char)(97 + i);
            if(skip.indexOf(alphabet) != -1) {
                continue;
            }
            exceptSkipChar.add(alphabet);
        }

        // String s를 한 글자씩 순회
        for(char c : s.toCharArray()) {
            // 해당 글자의 index에서 조건으로 주어진 index를 더한 값을 구하되, z를 넘어가면 다시 a(0번)으로 돌아와야 하니 나머지의 값을 구함
            int findIndex = (exceptSkipChar.indexOf(c) + index) % exceptSkipChar.size();
            
            // StringBuilder에 findIndex에 해당하는 값을 더함
            sb.append(exceptSkipChar.get(findIndex));
        }
        
        return sb.toString();
    }
}

📌 문제 풀이 설명

  • return 할 String을 만들기 위해 StringBuilder를 생성
  • Character를 저장할 exceptSkipChar라는 이름의 ArrayList를 생성
    • skip 글자들을 제외한 알파벳들을 저장할 배열
  • for문으로 0부터 26미만까지 1씩 증가하며 순회
    • char 변수 alphabet을 선언하고 97(a의 아스키코드) + i 를 char로 변환해 대입
      • a부터 z까지 저장하기 위해 순회하는 과정
    • 만약 skip에 alphabet의 index를 indexOf로 찾았을 때 -1이 아니면 skip의 요소 중 하나이므로 continue로 밑의 과정을 건너 뛰고 for문으로 감
      • = 해당 알파벳은 exceptSkipChar에 저장하지 않음
    • exceptSkipChar에 alphabet을 추가
  • 향상된 for문으로 s를 char 배열로 변경한 값을 순회
    • exceptSkipChar 배열에서 s의 요소(c)가 있는 인덱스를 찾고 변수 index의 값을 더한 뒤 exceptSkipChar의 size로 나눈 나머지를 findIndex에 대입
      • s의 요소에 해당하는 인덱스를 ArrayList에서 찾은 후 index 값을 더하면 출력해야 할 값의 인덱스를 찾을 수 있음
      • 다만, z에서 1을 더하면 다시 a로 가야 하는데 이걸 편하게 접근하려면 배열의 size로 나눈 나머지를 인덱스로 사용하면 됨
    • StringBuilder에 findIndex에 해당하는 값을 더함
  • 위 for문이 끝나면 StringBuilder를 String으로 변환해서 return

📌 주의했던 부분

  • 범위 안에 skip 요소가 있는 경우 찾아야 할 index +1을 하면 누락된 skip 요소가 생길 수 있음
    • 시작 글자가 x, index가 3, skip이 y와 b인 경우
      • x → y, z, a에 y가 있으니 +1 해서 b를 출력
      • 하지만 b도 skip이라 건너뛰어야 하는데 x에서 +3한 범위 내에서만 조사한 뒤 +1을 하기 때문에 해당 skip 요소가 적용이 안 됨
      • 해당 문제를 피하려면 한 번 다음 인덱스로 넘어갈 때마다 for문으로 모든 skip의 요소를 조사해야 함
  • skip을 오름차순으로 정렬해서 조사하면 생길 수 있는 오류
    • 시작 글자가 x, index가 3, skip이 y와 b인 경우
      • x에 해당하는 char는 x → y, z, a 순으로 순회할 예정
      • skip이 오름차순으로 정렬되어 b, y 순으로 되어 있다면, 처음에 b가 y, z, a에 포함되어 있지 않기 때문에 skip 처리되지 않음
      • 그 다음 skip 요소인 y는 포함되어 있어서 skip 처리
      • 그 다음에 skip 되어야 하는 b는 이미 검증된 걸로 처리되기 때문에 다시 확인하지 않아 오류 발생



👉 다른 사람이 작성한 답


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();
    }
}

📌 문제 풀이 설명

  • StringBuilder를 생성
  • 향상된 for문으로 s를 char 배열로 변경한 값을 순회
    • char 변수 temp에 s의 요소(letter) 대입
    • int 변수 idx를 선언하고 0으로 초기화
    • while문으로 idx가 index 미만일 때 순회
      • temp가 z와 같으면 a를 temp에 대입하고, 아니면 temp + 1한 char(temp의 다음 알파벳)를 대입
      • 만약 temp가 skip에 있지 않으면
        • idx에 +1
      • while문 종료 후 StringBuilder에 temp 추가
        • 간단하게 얘기하면 while문을 통해 바로 다음 요소들을 탐색하는데, idx로 몇 번째 다음 요소들을 탐색 중인지 확인하고, 만약 z인 경우의 다음 요소를 a로 넣음
  • for문 종료 후 answer를 String으로 변환해 return
profile
공부 중인 신입 백엔드 개발자입니다

0개의 댓글