개발야옹

[ 문자열 : lv2 ] 문자열 압축 (_JS) // fail 본문

Algorithm\CodingTest/Programmers

[ 문자열 : lv2 ] 문자열 압축 (_JS) // fail

kitez 2022. 1. 18. 19:12

프로그래머스 - 문자열 Lv2

문자열 압축 ( _JS )

 

문제 설명

 

제한 사항

 

입출력 예


문제 링크

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

 

코딩테스트 연습 - 문자열 압축

데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문

programmers.co.kr


코드

2022. 01. 17.

function solution(s) {
    var answer = 0;

    const len = s.length;

    let stack = [];
    let cur = "";
    let prev = "";
    let cnt  = 0 ;
    let result = "";

    let flag = true;

    let compareArr = [];

    if(len !== 1){
        for( let i = 2 ; Math.floor(len/i) >= 1 && flag ; i ++){
            if( Math.floor(len/i) === Math.floor(len/(i-1))){
                continue;
            }

            if( Math.floor(len/i) === 1){
                flag = false;
            }
            for( let j = 0; j <= Math.floor(len/Math.floor(len/i)) ; j++){
                console.log(j);
                if( j === Math.floor(len/Math.floor((len/i)))){
                    stack.push(s.substring((Math.floor(len/i) * j )));
                }
                else{
                    stack.push(s.substring((Math.floor(len/i) * j ), ( Math.floor(len/i) * (j+1))));
                }
            }

            stack.forEach( (item , index) => {
                cur = item;

                if( prev === cur){
                    cnt++;

                }

                if( prev !== cur && index !== 0){
                    // 이전값과 같지 않을 때
                    if( cnt > 0 ){
                        // 이미 앞에 same 있던 경우
                        result += String(cnt+1);
                        cnt = 0;
                        result += prev;
                    }
                    else{
                        // 앞에 same이 없던 경우
                        result += prev;
                    }
                }

                if(index+1 === stack.length && prev !== cur){
                    // 이전값과 현재 값이 같지 않을 때
                    // prev !== item
                    result += cur;
                }else if(index+1 === stack.length && prev === cur){
                    result += String(cnt+1);
                    result += cur;
                }

                prev = cur;
            });

            compareArr.push(result);

            // stack 초기화

            console.log("Stack : "+stack);
            result = "";
            stack.splice(0);
        }

        let min = 1000;
        let idx = 0;

        compareArr.forEach( (item, index) => {
            if( min >= item.length ){
                min = item.length;
                idx = index;
            }
        });

        return min;
    }
    else{
        // len === 1
        return 1;
    }
}

 

결과

테스트 2번과 15번을 통과 못하고 있는데 어떤 부분에서 예외처리를 제대로 해주지 못했는지 모르겠다... 


다른사람의 소스 코드 1

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

    for(var len=1;len<=s.length/2;len++){
        var str="";
        var idx=0;
        var tmp=s.substring(0,len);
        var cnt=1;
        for(idx=len;idx<=s.length;idx+=len){
            if(tmp===s.substring(idx,idx+len)){
                cnt++;
            }
            else{
                if(cnt===1) str+=tmp;
                else str+=cnt+tmp;
                cnt=1;
                tmp=s.substring(idx,idx+len);
            }
        }
        
        if(cnt===1) str+=tmp;
        else str+=cnt+tmp;
        
        answer=Math.min(answer,str.length);
    }
    return answer;
}

출처 : https://gwang920.github.io/algorithm/programmers-2-60057/

 

프로그래머스 - [Level 1] 문자열 압축(JAVASCRIPT)

프로그래머스 문자열 압축 [KAKAO]

gwang920.github.io


다른사람의 소스 코드 2

function solution(s) {
    let answer = 0;
    let left = '';
    let right = '';
    let result = [];
  
    for (let i = 1; i < Math.ceil(s.length / 2) + 1; i++) {
        result.push([]);
        // i = length
        let cnt = 1;
        for (let k = 0; k < s.length; k++) {
            left = s.substr(k * i, i);
            right = s.substr((k * i) + i, i);
            
            if (left === right) {
                cnt += 1;
            }
            else {
                // 똑같은 문자열이 있는 경우 숫자와 문자열을 같이 저장
                if (cnt > 1) {
                    result[i - 1] += String(cnt) + left;
                }
                // 똑같은 문자열이 없는 경우 문자열만 저장
                else {
                    result[i - 1] += left;
                }
                cnt = 1;
            }
        }
    }
    
    let min = result[0].length;
    for (let i in result) {
        if (min > result[i].length) {
            min = result[i].length;
        }
    }
    return min;
}

출처 : https://velog.io/@sqaurelu/ALGO-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%95%95%EC%B6%95%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-javascript

 

[ALGO] 프로그래머스 - 문자열 압축(자바스크립트, javascript)

데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문

velog.io

 


다른사람의 소스코드 1 이해하기

나는 len/2 => len/3 => len/4 순서로 크게크게 조각내서 비교를 했다면 이분은 작은 조각 => 큰 조각 순으로 비교를 하였다. 

하이라이트 되어 있는 부분인 첫 번재 for문이 바로 주어진 문자열을 조각내는 부분이다. 

해당 for문에서 var tmp = s.substring(0,len); 을 console.log로 찍어주면 아래와 같이 찍히는 것을 확인할 수 있다. 

// input string
"aaaaaaaaaabbccc"

console.log() 결과

 

두 번째 for문

두 번째 for문의 경우 첫 번째 for문에서 조각난 tmp를 제외한 뒷 부분의 문자열들을 tmp와 같은 크기로 조각내어 tmp값과 비교 한 후 tmp와 값이 같으면 counting 값인 cnt 값을 ++ 해준다. 

 

만약 tmp값과 같지 않으면서 cnt 값이 1인경우는 앞에서 tmp값과 same이었던 적이 없음으로 str에 tmp를  그대로 넣어주고, cnt를 1로 초기화 시켜 준 후 tmp값을 현재의 값으로 update해준다. => 다음 substring값과 같은지 비교하기 위해서

 

만약 tmp값과 같지 않으면서 cnt값이 1이 아닌 경우는 앞에서 tmp와 값이 같았던 적이 있음으로 cnt+tmp값을 str에 넣어주고 tmp값을 현재의 값으로 update해준다.

 

첫 번째 for문의 마지막 if~else 구문은 맨 마지막 문자의 처리를 해주는 것이다. 

 

그 다음 줄의 answer.Math.min(answer, str.length); => Math의 내장함수인 min()을 이용하여 answer와 str의 길이 중 더 짧은 값을 answer에 저장해준다. answer의 초깃값은 처음 들어온 string.length로 하나도 조각 나지 않는 경우도 있을 경우를 위해 string.length로 초기화를 시켜준 것이다. answer값을 for문을 돌 때마다 update되며 마지막에는 가장 작은 값으로 update되게 된다.

728x90