연속으로 반복되는 문자가 포함될 수 있는 문자열을 입력받아 압축하는 JavaScript 함수를 작성해 보겠습니다.
함수는 다음과 같은 방식으로 문자열을 압축해야 합니다.
'wwwaabbbb' → 'w3a2b4' 'kkkkj' → 'k4j'
단, 압축된 문자열의 길이가 원본 문자열의 길이보다 같거나 더 길어진다면 원본 문자열을 그대로 반환해야 합니다.
예를 들어 'aab'는 'a2b1'로 압축할 수 있지만, 이 경우 길이가 3에서 4로 오히려 늘어나기 때문에 함수는 원본인 'aab'를 그대로 반환해야 합니다.
구현 예제
위 요구 사항을 만족하는 코드는 다음과 같습니다.
const str1 = 'wwwaabbbb';
const str2 = 'kkkkj';
const str3 = 'aab';
const compressString = (str = '') => {
let res = '';
let count = 1;
for(let i = 0; i < str.length; i++){
const cur = str[i];
const next = str[i + 1];
if(cur === next){
count++;
} else {
res += cur + String(count);
count = 1;
}
}
return res.length < str.length ? res : str;
};
console.log(compressString(str1));
console.log(compressString(str2));
console.log(compressString(str3));코드 동작 방식
이 알고리즘은 문자열을 한 번만 순회하며 시간 복잡도는 O(n)입니다. 각 문자와 바로 다음 문자를 비교하여 두 문자가 같으면 카운트를 1 증가시키고, 다르면 현재 문자와 지금까지 센 개수를 결과 문자열에 추가한 뒤 카운트를 1로 초기화합니다.
순회가 끝난 후에는 압축 결과가 원본보다 실제로 짧아졌을 때만 압축 문자열을 반환하고, 그렇지 않으면 원본 문자열을 그대로 돌려줍니다. 덕분에 'aab'처럼 압축해도 오히려 길이가 늘어나는 경우를 자연스럽게 처리할 수 있습니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
w3a2b4 k4j1 aab