대문자와 소문자가 섞여 있는 문자열을 입력받아, 모든 대문자를 문자열 앞쪽으로 이동시킨 새로운 문자열을 반환하는 JavaScript 함수를 작성해야 합니다. 이때 중요한 조건은 각 문자들의 상대적인 순서가 그대로 유지되어야 한다는 점입니다.
예를 들어, 입력 문자열이 다음과 같다면 −
const str = 'heLLO woRlD';
기대하는 출력 결과는 다음과 같습니다 −
const output = 'LLORDhe wol';
해결 접근 방식
이 문제는 배열의 splice() 메서드를 활용하면 효율적으로 해결할 수 있습니다. 문자열을 한 글자씩 순회하면서 대문자인 경우에는 별도로 관리하는 인덱스 위치에 삽입하고, 소문자인 경우에는 배열의 끝에 추가하는 방식입니다. 대문자가 삽입될 때마다 해당 인덱스를 1씩 증가시키면, 대문자들 사이의 원래 순서가 자연스럽게 보존됩니다.
예제 코드
const str = 'heLLO woRlD';
const moveCapitalToFront = (str = '') => {
let capitalIndex = 0;
const newStrArr = [];
for(let i = 0; i < str.length; i++){
if(str[i] !== str[i].toLowerCase()){
newStrArr.splice(capitalIndex, 0, str[i]);
capitalIndex++;
}else{
newStrArr.push(str[i]);
};
};
return newStrArr.join('');
};
console.log(moveCapitalToFront(str));출력 결과
콘솔에 출력되는 결과는 다음과 같습니다 −
LLORDhe wol
코드 동작 원리
1. capitalIndex 변수는 대문자가 삽입될 위치를 추적하며, 초기값은 0입니다.
2. str[i] !== str[i].toLowerCase() 조건을 통해 현재 문자가 대문자인지 판별합니다. 소문자로 변환했을 때 값이 달라진다면 그 문자는 대문자입니다.
3. 대문자라면 newStrArr.splice(capitalIndex, 0, str[i])로 해당 위치에 삽입한 후 capitalIndex를 증가시켜 다음 대문자가 그 뒤에 오도록 합니다.
4. 소문자라면 newStrArr.push(str[i])로 배열 맨 뒤에 추가하여 기존 소문자들의 순서도 유지됩니다.
5. 마지막으로 join('')을 사용해 배열을 하나의 문자열로 합쳐 반환합니다.
이 알고리즘은 문자열을 한 번만 순회하므로 시간 복잡도는 O(n)이지만, splice() 연산이 내부적으로 요소들을 이동시키기 때문에 실제 성능은 O(n²)에 가까울 수 있습니다. 더 나은 성능이 필요하다면 대문자와 소문자를 각각 별도의 배열에 담은 후 마지막에 두 배열을 연결(concat)하는 방식도 고려해볼 수 있습니다.