반복되는 문자를 포함하는 문자열을 입력받아, 같은 문자들이 서로 정확히 n칸씩 떨어지도록 재배열한 새 문자열을 반환하는 JavaScript 함수를 작성해야 합니다. 이때 n은 문자열 길이보다 작은 값이어야 합니다.
문제 예시
입력 문자열: "accessories" n = 3 반환값: "secrsecisao"
참고: 조건을 만족하는 결과 문자열은 여러 가지가 존재할 수 있습니다. 순서는 중요하지 않으며, 로직상 요구 사항을 충족하기만 하면 그 출력은 올바른 것으로 간주됩니다.
접근 방식
1. 문자별 빈도수 집계
split("")으로 문자열을 개별 문자로 나눈 뒤, reduce()와 Map 객체를 활용해 각 문자가 몇 번 등장하는지 집계합니다.
2. 빈도수 기준 내림차순 정렬
Map을 배열로 변환한 후, 등장 횟수가 많은 문자부터 처리하도록 내림차순으로 정렬합니다. 빈도가 높은 문자를 먼저 배치해야 나중에 같은 문자가 n 간격 이내에 중복 배치되는 상황을 피할 수 있습니다.
3. n 주기로 문자 배치
for 반복문에서 i % num을 이용해 인덱스를 0부터 num-1까지 순환시키며, 각 위치에 해당하는 문자를 결과 문자열에 추가하고 남은 개수를 하나씩 줄입니다. 남은 개수가 0이 된 문자는 배열에서 제거하여 더 이상 선택되지 않도록 합니다.
코드 구현
const str = 'accessories';
const equalDistance = (str, num) => {
const map = str.split("").reduce((acc, val) => {
const count = acc.get(val);
if(typeof count === 'number'){
acc.set(val, count+1);
}else{
acc.set(val, 1);
};
return acc;
}, new Map());
const arr = Array.from(map).sort((a, b) => b[1] - a[1]);
let newString = '';
for(let i = 0, count = 0; i < str.length;){
if(!arr[count][1]){
arr.splice(count, 1);
continue;
};
newString += arr[count][0];
arr[count][1]--;
i++;
count = i % num;
};
return newString;
};
console.log(equalDistance(str, 4));
console.log(equalDistance('abb', 2));
console.log(equalDistance('aacbbc', 3));실행 결과
콘솔에는 다음과 같이 출력됩니다.
sceasceosri bab acbacb
'abb'를 간격 2로 재배열하면 'bab'처럼 두 a가 정확히 2칸 떨어지고, 'aacbbc'를 간격 3으로 재배열하면 'acbacb'처럼 모든 같은 문자가 3칸 간격으로 배치되는 것을 확인할 수 있습니다.