Java Coding Test ( 둘만의 암호 )

song yuheon·2023년 9월 8일
0

Java Algorithm

목록 보기
7/18
post-thumbnail

문제 링크


문제 설명


두 문자열 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"

입출력 예 설명

입출력 예 #1
본문 내용과 일치합니다.


구현 전략


  1. 문자열 s를 문자 배열 h 로 만들고 반복 문으로 돌린다.
  2. 문자 배열 h안에 index 값을 설정할 ( skip 값을 반영한 ) 반복문을 돌린다.
  3. if문을 통해 alphabet 범위를 초과하는 문자들을 처리한다.

구현


1차 시도

class Solution {
    public String solution(String s, String skip, int index) {
        String answer = "";
        for (char c : s.toCharArray()) {
            char [] tempSkip = skip.toCharArray();
            for (int i = 0; i < tempSkip.length; i++)
                if(c+i==tempSkip[i])
                    index++;

            if((c+index>'z'&&c+index<'a') || (c+index>'Z' && c+index<'A'))
                answer+=(char)(c+index-26);
            else
                answer+=(char)(c+index);

        }
        System.out.println("answer = " + answer);

        return answer;
    }
}

  • 예상과 다른 결과 발생
    -> 디버깅을 통해 문제 해결

문제 원인 : index를 다시 초기화 해주는 로직이 없었다.

해당 로직을 추가 하였지만 여전히 문제 발생

디버깅 결과 로직 자체에 문제가 있었음을 확인

이중 for문으로 index 범위에 따른 반복문과 skip 범위의 반복문이 필요하다는 것을 확인

및에 인덱스 적용하는 if문 또한 로직의 오류 확인
수정후 진행하니 오류 해결

class Solution {
    public String solution(String s, String skip, int index) {
        String answer = "";
        int tempIndex = 0;
        for (char c : s.toCharArray()) {
            tempIndex = index;
            char [] tempSkip = skip.toCharArray();
            for (int j = 0; j < index+1; j++)
                for (int i = 0; i < tempSkip.length; i++)
                    if((char)(c+j)==tempSkip[i])
                        tempIndex++;


            if(c>='a'&&c<='z')
                if(c+tempIndex>'z')
                    answer+=(char)(c+tempIndex-26);
                else
                    answer+=(char)(c+tempIndex);
            else if(c>='A'&&c<='Z')
                if(c+tempIndex>'Z' )
                    answer+=(char)(c+tempIndex-26);
                else
                    answer+=(char)(c+tempIndex);
            else{
                return "error";
            }
        }
        System.out.println("answer = " + answer);

        return answer;
    }
}

=> 여전히 오류 발생
문제를 다시 본 결과 한 가지 문제점을 발견

  • 문자를 건너뛰는 로직에서 tempIndex를 단순히 증가시키는 방식은 문제의 요구 사항을 충족시키지 못한다는 것이다..

따라서 코드의 로직을 최소화하고 효율적으로 재구성 하는 것이 필요


구현 전략 재구성


  1. 기존에 이중 반복문은 너무 가독성이 안 좋고 비효율적이라 판단
    -> set을 사용
  2. 조건을 살펴보면 s와 skip은 알파벳 소문자로 구성 -> 대문자 처리 불 필요
  3. 문자 건너뛰는 로직 해결을 위해 while문 사용
class Solution {
    public String solution(String s, String skip, int index) {
        String answer = "";
        int tempIndex;
        /**
         * skip 문자열을 Set에 저장
         */
        Set<Character> skipSet = new HashSet<>();
        for(char c : skip.toCharArray())
            skipSet.add(c);
        
        
        for (char c : s.toCharArray()) {
            tempIndex = index;
            char tempChar = c;
            /**
             * skipSet에 포함되어있는 문자는 건너뛰고 index를 1씩 감소시킨다.
             * index가 0이 될때까지 반복한다.
             * index가 0이 되면 해당 문자를 answer에 추가한다.
             * index가 0이 되기 전에 문자열의 끝에 도달하면 문자열의 처음으로 돌아간다.
             */
            while(tempIndex>0){
                tempChar++;
                if(tempChar>'z')
                    tempChar = 'a';
                if(!skipSet.contains(tempChar))
                    tempIndex--;
            }
            answer+=tempChar;

        }
        return answer;
    }
}


profile
backend_Devloper

0개의 댓글