알고리즘 문제 풀기

프로그래머스: 문자열 압축 - javascript(반복문 관건)

Fo_rdang 2024. 4. 24. 11:19
반응형

문제 출처 

https://school.programmers.co.kr/learn/courses/30/lessons/60057

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 풀이 힌트 

01. 해당하는 s에서 단위가 될 수 있는건 1 ~ Math.ceil(s.length/2) 까지다. => 반복문을 통해 접근

02. 해당하는 단위에 따라서 s를 slice를 통해 해당 idx에 해당하는 문자와 그 다음 문자를 구한다. 

03. 두 문자를 비교해서 같다면, cnt+1 

04. 두 문자를 비교해서 같지 않다면 지금까지 cnt랑 문자를 압축한걸 answer = '' 에 추가한다. cnt는 초기화한다.

05.  해당하는 단위에 따른 문자열을 반복문 다 돌면서 압축 문자열을 완성했다면, 해당 길이를 compressedLength 배열에 저장한다. 

06. 단위를 도는 반복문도 끝나면 compressedLength 배열에 저장된 숫자들 중 가장 Math.min 값을 return 한다. 

 

문제 풀이 코드 

function solution(s) {
    let answer = ''; //압축한 문자열 
    const compressedLength = []; //압축한 문자열의 길이들 저장하는 배열 
    
    for(let unit = 1; unit<=  Math.ceil(s.length/2); unit++){ //단위 1부터 s.length의 반까지 
        for(let idx=0, cnt=1; idx < s.length; idx += unit){//해당 단위로, s전체를 반복문으로 돌아서 압축
            const pattern = s.slice(idx, idx+unit) //단위에 해당하는 문자
            const nextChars = s.slice(idx+unit, idx + 2*unit) //단위에 해당하는 다음 문자
            if(pattern === nextChars){ //현재 문자 === 다음 문자일 때, 
                cnt++; //같은 문자 수 +1
                continue; //반복문 계속 지속 
            }else{ //현재 문자 !== 다음 문자 일 때, 
                cnt = cnt === 1 ? '' : cnt;  //cnt1가 1이라면 숫자는 없어야 한다. 
                answer += `${cnt}${pattern}` //answer에 지금까지 합축하는 문자 넣어준다. 
                cnt = 1; //cnt는 다시 1로 reset한다. 
            }
        }
        const wordLength = answer.length; //s를 다 돌고 완성한 압축 문자열의 길이 wordLength
        compressedLength.push(wordLength); //해당 길이를 저장해둔다. 
        answer = ''; //해당 단위에 해당하는 압축문자열 reset 
    }
    return Math.min(...compressedLength); //단위에 따른 모든 압축문자열 길이 중 가장 짧은거 return 
}

 

Only 풀이 코드 

function solution(s) {
    let answer = ''; 
    const compressedLength = []; 
    const MAX_REPETITION = s.length; 
    
    for(let unit = 1; unit<=  MAX_REPETITION; unit++){
        for(let idx=0, cnt=1; idx < MAX_REPETITION; idx += unit){
            const pattern = s.slice(idx, idx+unit)
            const nextChars = s.slice(idx+unit, idx + 2*unit)
            if(pattern === nextChars){
                cnt++; 
                continue; 
            }else{
                cnt = cnt === 1 ? '' : cnt; 
                answer += `${cnt}${pattern}`
                cnt = 1; 
            }
        }
        const wordLength = answer.length; 
        compressedLength.push(wordLength); 
        answer = ''; 
    }
    return Math.min(...compressedLength); 
}

 

나의 틀린 풀이 코드 (전체에서 실패1) 

- 반복문에서 Math.floor(s.length/2)가 아닌, Math.ceil(s.length/2)로 변경하면 성공 ! 

function solution(s) {
    let answer = Number.MAX_SAFE_INTEGER; 
  for(let i=1; i<=parseInt(s.length/2); i++){
     let len = check(s, i); 
     answer =  Math.min(answer, len)
  }
   return answer; 
}
//s를 unit 별로 잘라서 새로운 문자열의 길이를 반환하는 함수 
//-s를 unit 별로 잘라서 배열로 만들어 
//-그리고 그 배열을 계속 앞뒤로 비교해서 같다면 숫자 cnt++; 
//-resut에 더하면서 완성 
//-return result.length; 
function check(s, unit){
    let result = ''
    let temp = []; 
    for(let i=0; i<s.length; i+= unit){
      temp.push(s.slice(i, i+unit));    
    }
   let idx = 0; 
while(idx < temp.length){
    let cnt = 1; 
    while(temp[idx] === temp[idx+1]){
        idx++; 
        cnt++; 
  }
    result += `${cnt > 1 ? cnt : ''}${temp[idx]}`
    idx++; 
}
    return result.length; 
    }
//문자열 압축 
//같은 값이 연속해서 나타나는 것을 그 문자의 개수와 반복되는 값으로 표현
//1개 이상의 단위로 잘라서 압축 표현 
//retrun 가장 짧은 것의 길이 

//s는 1이상 1000이하 
//소문자로 이뤄짐 

//큰 반복문 1단위 ~ 해당 s의 길이 반까지 
//+함수 해당 단위만큼의 문자열 반복문 
//-현재 문자열이랑 다음 문자열이 다르기 전까지 cnt 세준다. 
//return

 

반응형