코딩테스트 회고록/코테_Java

[JAVA] 프로그래머스 - 둘만의 암호

2024. 3. 8. 02:04
목차
  1. ❓ 문제 설명
  2. ⚠️ 입출력 예시
  3. 🔍 마주한 문제와 해결 과정
  4. ✏️ 정답 코드
  5. ⭐ 한 번 짚고 넘어갈 !

프로그래머스 코딩테스트 연습 Lv.1 '둘만의 암호' 문제 풀이와 풀이과정 입니다.

 

https://school.programmers.co.kr/learn/courses/30/lessons/155652?language=java

 

프로그래머스

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

programmers.co.kr

 


❓ 문제 설명

두 문자열 s와 skip, 그리고 자연수 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"가 됩니다.

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

 

 

< 제한사항>

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

⚠️ 입출력 예시

입력 ▼

// s
"aukks" 

// skip
"wbqd"

// index
5

 

출력 ▼

"happy"

🔍 마주한 문제와 해결 과정

가장 처음에는

문자열에 replace(없앨 문자, "") 메서드를 사용하면 쉽게 알파벳을 제거할 수 있기에

afterS라는 문자열 변수를 이용해 skip에 포함된 알파벳을 제거하려 했습니다.

 

또한 아스키코드를 활용해 a~z 알파벳을 가져왔습니다.

// 틀린 코드 입니다.
class Solution {
    public String solution(String s, String skip, int index) {
        String answer = "";
        String[] skipArray = skip.split("");
        
        for(int i = 0; i < s.length(); i++) {
            String afterS = "";
            
            int before = s.charAt(i);
            
            int j = 1;
            // index만큼 뒤에 있는 알파벳 구하기
            while(afterS.length() <= index){
                // skip 알파벳 제거
                for(int k = 0; k < skipArray.length; k++) {
                    afterS = afterS.replace(skipArray[k], "");
                }
                
                // afterS에 알파벳을 계속 더하면서 값 찾아내기
                // z의 아스키코드와 같거나 커지면 26을 빼서 다시 a로 돌아가게
                if((before+j) >= 123) {
                        afterS += (char)((before+j)-26);
                    } else {
                        afterS += (char)(before+j);
                    }
                
                j++;
            }
            
            answer += afterS.substring(index-1, index);
            
        }
        
        return answer;
    }
}

 

하지만!!!!!

 

이 사진처럼 케이스 3,17,18,19에서 통과하지 못했습니다.

 

단순하게 26을 뺀 부분에서 문제가 있었습니다.

a~z의 개수가 26개 이므로 z의 아스키코드값을 넘어가면 그 개수만큼을 빼면 해결된다고 생각했지만

 

만약 제외할 알파벳인 skip의 개수가 많다면 26을 빼도 a~z의 아스키코드 범위를 벗어나게 됩니다.

딱 26만 빼면 다른 이상한 문자가 나올 수 있다는 것입니다.


✏️ 정답 코드

class Solution {
    public String solution(String s, String skip, int index) {
        String answer = "";
        String[] skipArray = skip.split("");
        
        for(int i = 0; i < s.length(); i++) {
            String afterS = "";
            
            int before = s.charAt(i);
            
            int j = 1;
            // index만큼 뒤에 있는 알파벳 구하기
            while(afterS.length() <= index){
                // skip 알파벳 제거
                for(int k = 0; k < skipArray.length; k++) {
                    afterS = afterS.replace(skipArray[k], "");
                }
                
                // *** 해결한 부분
                afterS += (char)((before+j)-26*((before+j-97)/26));
                
                j++;
            }
            
            answer += afterS.substring(index-1, index);
            
        }
        
        return answer;
    }
}

 

before+j의 값이 a~z 아스키코드의 범위를 한참 벗어난다해도 26을 몇 배씩 곱한 후 뺀다면

a~z 아스키코드의 범위안의 값을 찾게 됩니다.


⭐ 한 번 짚고 넘어갈 !

  • 아스키코드 -> 문자
// (char) 캐스팅

afterS = (char)(before+j)

 

  • 문자 -> 아스키코드
// charAt() 사용

int before = s.charAt(1); // 인자는 몇 번째 문자를 가져올 것인지에 대한 index번호

 

  • replace(), replaceAll()로 문자열의 특정 문자 제거 가능

https://codingismylife.tistory.com/56

 

[JAVA] 메서드 - replace(), replaceAll()

🤔 어떤 메서드일까? replace() 와 replaceAll() 메서드는 문자열의 특정 문자를 원하는 문자로 변환하는 메서드입니다. replace() replace(CharSequence target, CharSequence replacement) 첫 번째 매개변수는 변환하고

codingismylife.tistory.com

 

'코딩테스트 회고록 > 코테_Java' 카테고리의 다른 글

[JAVA] 프로그래머스 - n^2 배열 자르기 (1편)  (0) 2024.03.21
[JAVA] 프로그래머스 - 등차수열의 특정한 항만 더하기  (0) 2024.03.12
[JAVA] 프로그래머스 - A 강조하기  (0) 2023.05.02
[JAVA] 프로그래머스 - 옹알이(1)  (0) 2023.04.05
[JAVA] 프로그래머스 - 문자열안에 문자열  (0) 2023.04.05
  1. ❓ 문제 설명
  2. ⚠️ 입출력 예시
  3. 🔍 마주한 문제와 해결 과정
  4. ✏️ 정답 코드
  5. ⭐ 한 번 짚고 넘어갈 !
'코딩테스트 회고록/코테_Java' 카테고리의 다른 글
  • [JAVA] 프로그래머스 - n^2 배열 자르기 (1편)
  • [JAVA] 프로그래머스 - 등차수열의 특정한 항만 더하기
  • [JAVA] 프로그래머스 - A 강조하기
  • [JAVA] 프로그래머스 - 옹알이(1)
iamjisu
iamjisu
글 솜씨는 없지만 한 글자 한 글자 정성을 다해, 새롭게 배운 것을 정리하고 공부하는 코딩 성장 일기!!
iamjisu
지수의 코딩 발자국
iamjisu
전체
오늘
어제
github 링크
  • 카테고리
    • 개념정리
      • CS
      • MySQL
      • JavaScript
      • Kotlin
      • Java
      • NodeJS
      • Android
    • 코딩테스트 회고록
      • 코테_Java
      • 코테_C언어
    • 오류해결

최근 글

최근 댓글

hELLO · Designed By 정상우.
iamjisu
[JAVA] 프로그래머스 - 둘만의 암호
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.