문제
https://school.programmers.co.kr/learn/courses/30/lessons/155652
문제 설명
두 문자열 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 | skip | index | result |
|---|---|---|---|
| "aukks" | "wbqd" | 5 | "happy" |
입출력 예 설명
입출력 예 #1
본문 내용과 일치합니다.
풀이
class Solution {
public String solution(String s, String skip, int index) {
// StringBuilder는 문자열을 반복해서 붙일 때 성능이 좋음
// (일반 문자열 + 연산보다 훨씬 빠름)
StringBuilder answer = new StringBuilder();
// 알파벳 a~z 총 26개이므로 크기가 26인 boolean 배열 생성
// 예: isSkip[0] == true → 'a'는 skip 문자
// isSkip[1] == true → 'b'는 skip 문자
boolean[] isSkip = new boolean[26];
// skip 문자열에 포함된 문자들을 배열에 표시
for (char c : skip.toCharArray()) {
// 'a'를 0으로 기준으로 삼기 위해
// 예: 'a' - 'a' = 0, 'b' - 'a' = 1 ... 'z' - 'a' = 25
isSkip[c - 'a'] = true;
}
// 문자열 s의 각 문자를 하나씩 처리
for (char ch : s.toCharArray()) {
// index만큼 뒤로 이동한 실제 횟수 (skip 포함 X)
int moveCount = 0;
// 현재 문자를 숫자로 변환 (‘a’를 0으로 봄)
// 예: ch = 'c' → current = 2
int current = ch - 'a';
// index만큼 'skip이 아닌' 문자들만 세며 뒤로 이동
while (moveCount < index) {
// 알파벳 한 칸 뒤로 이동
current++;
// 'z'를 넘어가면 다시 'a'로 돌아가야 하므로 26을 넘는지 확인
// 알파벳 인덱스는 0~25까지이므로 25보다 크면 다시 0으로
if (current > 25) {
current = 0;
}
// 이동한 위치의 알파벳이 skip에 포함되어 있으면
// 이동 횟수(moveCount)에 포함하지 않고 그냥 넘어감
if (isSkip[current]) {
// skip 문자이므로 count 증가 없이 다음 루프로 이동
continue;
}
// skip이 아닌 정상 문자면 이동 횟수 1 증가
moveCount++;
}
// ---------------------------
// !!! 매우 중요한 부분 !!!
// current는 0~25 범위의 숫자임
// 이 숫자를 다시 실제 알파벳 문자로 변환해야 함
//
// 예: current = 0 → 'a'
// current = 1 → 'b'
// current = 7 → 'h'
//
// 문자로 만드는 방법: (char)(숫자 + 'a')
// 'a'는 아스키 코드 97이므로,
// (current + 'a') 하면 -> 해당 알파벳의 아스키 코드 값이 됨.
// 그걸 char로 바꾸면 실제 문자로 변환됨.
// ---------------------------
answer.append((char)(current + 'a'));
}
// 최종 변환된 문자열 반환
return answer.toString();
}
}
class Solution {
public String solution(String s, String skip, int index) {
// 결과 문자열을 효율적으로 만들기 위한 StringBuilder 사용
StringBuilder result = new StringBuilder();
// skip 에 포함된 문자를 빠르게 체크하기 위해 boolean 배열 생성
// 알파벳 26개(a~z)를 담을 수 있음
boolean[] skipTable = new boolean[26];
// skip 문자열의 각 문자를 skipTable에 표시
for (char c : skip.toCharArray()) {
skipTable[c - 'a'] = true;
}
// s의 각 문자(letter)를 변환
for (char letter : s.toCharArray()) {
// 현재 위치에서 변환한 알파벳을 담는 변수
char current = letter;
// skip이 아닌 문자를 index번 이동한 횟수
int movedCount = 0;
// movedCount가 index에 도달할 때까지 반복
while (movedCount < index) {
// 알파벳을 1칸 뒤로 이동
// 'z' 다음은 'a'로 순환되도록 처리
current = (current == 'z') ? 'a' : (char)(current + 1);
// current가 skipTable에 표시되어 있다면 skip 문자 → 이동 횟수 증가 X
if (skipTable[current - 'a']) {
continue;
}
// skip이 아닐 경우 정상적인 이동 → 이동 횟수를 1 증가
movedCount++;
}
// 변환이 끝난 current 문자를 결과에 추가
result.append(current);
}
// 최종 암호화된 문자열 반환
return result.toString();
}
}'Algorithm > Programmers' 카테고리의 다른 글
| [Programmers] Lv.1 | 카드 뭉치 | Java (0) | 2025.11.20 |
|---|---|
| [Programmers] Lv.1 | 대충 만든 자판 | Java (0) | 2025.11.18 |
| [Programmers] Lv.1 | 덧칠하기 | Java (0) | 2025.11.17 |
| [Programmers] Lv.1 | 바탕화면 정리 | Java (0) | 2025.11.15 |
| [Programmers] Lv.1 | 공원 산책 | Java (0) | 2025.11.13 |
댓글