JavaScript에서 첫 번째 인수로 문자열을, 두 번째 인수로 숫자 n, 세 번째 인수로 문자 c를 받는 함수를 작성해 보겠습니다. 이 함수는 문자열에 등장하는 모든 문자의 n번째 출현을 세 번째 인수로 전달된 문자로 교체한 새로운 문자열을 반환해야 합니다.
예를 들어 문자열이 'This is a sample string'이고 n이 2, 교체할 문자가 '*'라면, 각 문자가 두 번째로 나타나는 자리만 별표(*)로 바뀐 새 문자열이 반환되어야 합니다.
구현 코드
이 함수는 다음과 같이 작성할 수 있습니다.
const str = 'This is a sample string';
const num = 2;
const char = '*';
const replaceNthAppearance = (str, num, char) => {
const creds = str.split('').reduce((acc, val, ind, arr) => {
let { res, map } = acc;
// 해당 문자가 처음 등장하는 경우
if(!map.has(val)){
map.set(val, 1);
if(num === 0){
res += char;
}else{
res += val;
}
}else{
// 이미 등장했던 문자라면 빈도를 확인
const freq = map.get(val);
if(num - freq === 1){
// 현재 위치가 정확히 n번째 등장이라면 교체
res += char;
}else{
res += val;
}
map.set(val, freq+1);
}
return { res, map };
}, {
res: '',
map: new Map()
});
return creds.res;
}
console.log(replaceNthAppearance(str, num, char));
출력 결과
콘솔에는 다음과 같이 출력됩니다.
This ***a s*mple string
코드 동작 원리
이 코드의 핵심 로직은 다음과 같습니다.
1. 문자 분리 및 누적 처리: split('')으로 문자열을 개별 문자 배열로 만든 뒤, reduce()를 사용해 결과 문자열(res)과 각 문자의 등장 횟수를 기록하는 Map 객체(map)를 함께 관리합니다.
2. 첫 등장 여부 확인: Map에 해당 문자가 없다면 처음 등장한 것이므로 원래 문자를 그대로 추가하고 빈도를 1로 기록합니다. 단, n이 0으로 주어진 경우에는 모든 첫 등장을 교체 문자로 바꿉니다.
3. n번째 등장 판별: 이미 등장한 문자라면 기존 빈도(freq)를 확인합니다. num - freq === 1이라는 조건은 "이전까지 freq번 등장했으므로 현재가 정확히 n번째 등장"임을 의미하며, 이 경우에만 교체 문자로 대체합니다. 그 외의 경우에는 원래 문자를 유지하고 빈도를 1 증가시킵니다.
이처럼 Map을 활용해 각 문자의 등장 횟수를 추적하면, 문자열을 한 번만 순회하면서 모든 문자의 n번째 출현을 효율적으로 교체할 수 있습니다.