본문 바로가기

코딩테스트/프로그래머스

[Javascript] 문자열 압축 (60057)

문제링크

 

접근 방법

문자열을 1개부터 문자열/2개까지 반복하여 잘라 비교하는 방식으로 접근하였다.

"ababcdcdababcdcd"
a b a b c d c d a b a b c d c d
ab ab cd cd ab ab cd cd => 2ab 2cd 2ab 2cd를 우선 저장
aba bcd cda bab cdc d
abab cdcd abab cdcd
ababc dcdab abcdc d
ababcd cdabab cdcd
ababcdc dababcd cd
ababcdcd ababcdcd => s.length / 2 까지만 검사, 2ab 2cd 2ab 2cd를 2ababcdcd로 대체

첫 for문에서 몇개씩 자를지 판단하고
2번째 for문에서 문자열 전체를 비교하는 방식으로 접근하였다.
let answer = s.length;
    
for (let i = 1; i <= s.length / 2; i++){
    let compressedStr = "";
    let count = 1;
    for( let j = i; j <= s.length; j += i){
    	console.log(`i : ${i}, j : ${j}`)
        if(s.slice(j-i,j) === s.slice(j,j+i))
            count += 1; 
        else{
            compressedStr += (count > 1 ? count : "") + s.slice(j-i, j)
            count = 1;
        }
    }
    console.log(compressedStr)
    answer = Math.min(answer, compressedStr.length);
}​

처음 작성한 코드인데 console.log(compressedStr)을 출력해보면 위에서 연한 붉은 배경으로 표시한 문자열
(즉 딱 나누어 떨어지지 않는 부분)을 받아오지 못했다.

이를 받아오기 위해서는 두번째 for문에서 s.slice(j+i, s.length)을 문자열 끝에 추가해야하는데 
두번째 for문에서는 j가 끝없이 변화하기 때문에
두번째 for문 밖에서 변수 prev를 만들어 접근하는 방식으로 풀이를 진행하였다. 



function solution(s) {
    let answer = s.length;

    for (let i = 1; i <= s.length / 2; i++){
        
        let prev = s.slice(0, i);
        let compressedStr = "";
        let count = 1;
        
        for( let j = i; j <= s.length; j += i){
            
            let next = s.slice(j, j+i);
            
            if (prev === next) 
                count += 1; 
            else{
                compressedStr += (count > 1 ? count : "") + s.slice(j-i, j)
                count = 1;
                prev = next;
            }
        }
        
        compressedStr += (count > 1 ? count : "") + prev
        answer = Math.min(answer, compressedStr.length);
        
    }
    
    return answer;
}