URL : https://school.programmers.co.kr/learn/courses/30/lessons/155652
JS
문제
문제 설명
두 문자열 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
본문 내용과 일치합니다.
계획
문자열을 배열로 만들기
제외목록의 알파벳인지 확인
문자열 s의 각 알파벳을 index만큼 뒤의 알파벳으로 바꾸기
참고, 풀이
const char = 'A'; // 변환할 문자
const asciiCode = char.charCodeAt(0); // 첫 번째 문자의 아스키코드 반환
console.log(asciiCode); // 출력: 65
const asciiCode = 65; // 변환할 아스키코드 번호
const char = String.fromCharCode(asciiCode); // 아스키코드를 문자로 변환
console.log(char); // 출력: 'A'
답
function solution(s, skip, index) {
// 문자열을 배열로 만들기
let sArr = [...s];
// 제외목록을 아스키코드 배열로 변환하고 정렬하기
const skipArr = [...skip].map((char) => char.charCodeAt(0)).sort((a, b) => a - b);
// 각 문자를 변환
let result = sArr.map((char) => {
let charCode = char.charCodeAt(0); // 변환할 문자의 아스키코드
let steps = 0; // 실제 이동한 거리
// 제외 목록을 고려하여 실제 이동할 거리 계산
for (let i = 0; steps < index; i++) {
charCode++; // 알파벳 이동
if (charCode > 122) charCode = 97; // 'z' 다음에는 'a'로 순환
// 제외 목록에 없는 경우에만 steps 증가
if (!skipArr.includes(charCode)) {
steps++;
}
}
// 변환된 문자 반환
return String.fromCharCode(charCode);
});
// 배열을 문자열로 변환하여 반환
return result.join("");
}
코드 간략화하기
function solution(s, skip, index) {
const skipSet = new Set([...skip].map((c) => c.charCodeAt(0))); // 제외 목록을 Set으로 저장
return [...s].map((c) => {
let charCode = c.charCodeAt(0);
for (let steps = 0; steps < index; charCode++) {
if (charCode > 122) charCode = 97; // 'z' 다음에는 'a'로 순환
if (!skipSet.has(charCode)) steps++;
}
return String.fromCharCode(charCode);
}).join('');
}
다른사람 답
function solution(s, skip, index) {
const alphabet = [...'abcdefghijklmnopqrstuvwxyz'].filter(c => !skip.includes(c));
return s.split("").map(c => alphabet[(alphabet.indexOf(c) + index) % alphabet.length]).join("");
}
function solution(s, skip, index) {
const skipSet = new Set(skip); // skip 문자열의 문자를 Set으로 변환하여 검색 효율화
const alphabet = 'abcdefghijklmnopqrstuvwxyz'; // 알파벳 전체 문자열
const filtered = [...alphabet].filter(ch => !skipSet.has(ch)); // skip 문자를 제외한 유효 알파벳 배열
return [...s].map(char => {
const currentIndex = filtered.indexOf(char); // 현재 문자의 위치
const newIndex = (currentIndex + index) % filtered.length; // 이동 후의 위치
return filtered[newIndex]; // 변환된 문자 반환
}).join(''); // 최종 문자열 반환
}
function solution(s, skip, index) {
const able = 'abcdefghijklmnopqrstuvwxyz'
.replace(new RegExp(skip.split('').join('|'), 'g'), '');
return s
.split('')
.map(e => able[(able.indexOf(e) + index) % able.length])
.join('');
}
주어진 문자 집합(able)에서 특정 문자를 건너뛰고(skip), 주어진 index만큼 이동한 결과를 반환하는 방식
1. able 변수 생성
const able = 'abcdefghijklmnopqrstuvwxyz'
.replace(new RegExp(skip.split('').join('|'), 'g'), '');
- 'abcdefghijklmnopqrstuvwxyz': 알파벳 소문자들을 문자열로 나타냄.
- skip.split('').join('|'): skip 문자열을 문자 하나씩 나눈 뒤, 이를 정규식으로 사용할 수 있도록 '|'(OR 연산자)로 연결.
- 예: skip이 "aeiou"라면 결과는 "a|e|i|o|u".
- new RegExp(..., 'g'): 정규식을 생성하고, 문자열 전체에서(g: global) 일치하는 부분을 찾아 제거.
- replace: skip에 포함된 문자를 able 문자열에서 제거.
- 예: skip = "aeiou"라면 able은 "bcdfghjklmnpqrstvwxyz"가 됨.
2. s 문자열 변환
return s
.split('')
.map(e => able[(able.indexOf(e) + index) % able.length])
.join('');
- s.split(''): 문자열 s를 각 문자로 나눠 배열로 만듦.
- 예: s = "abc"라면 결과는 ['a', 'b', 'c'].
- .map(...): 배열의 각 요소(e)를 변환.
- able.indexOf(e): e 문자가 able에서 몇 번째 위치인지 찾음.
- 예: able = "bcdfghjklmnpqrstvwxyz", e = 'b'라면 able.indexOf('b')는 0.
- (able.indexOf(e) + index) % able.length: index만큼 이동한 새로운 위치를 계산. % able.length는 배열의 길이를 넘어가는 경우 순환하도록 함.
- 예: able.length = 21이고, index = 2라면, 이동 후 위치는 (현재 위치 + 2) % 21.
- able[...new index...]: 새로운 위치에 있는 문자를 가져옴.
- able.indexOf(e): e 문자가 able에서 몇 번째 위치인지 찾음.
- .join(''): 변환된 문자 배열을 다시 문자열로 합침.
참고
https://hianna.tistory.com/409
'내일배움 과제 > 코딩테스트' 카테고리의 다른 글
알고리즘 66번 - 대충 만든 자판 (0) | 2025.01.25 |
---|---|
알고리즘 65번 - 문자열 나누기 (1) | 2025.01.24 |
알고리즘 64번 - 체육복 (0) | 2025.01.23 |
알고리즘 63번 - 숫자짝꿍 (0) | 2025.01.22 |
알고리즘 62-옹알이(2) (0) | 2025.01.21 |