본문 바로가기
일반 학습/코딩 테스트

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

by StelthPark 2022. 3. 4.

 

function solution(s) {
  let answer = s.length;
  for (let i = 1; i <= parseInt(s.length / 2); i++) {
    let cnt = 1;
    let tempStr = s.substr(0, i);
    let str = "";
    let idx = 0;
    for (idx = i; idx < s.length; idx += i) {
      let nextStr = s.substr(idx, i);
      if (tempStr === nextStr) cnt++;
      else {
        if (cnt === 1) {
          str = str + tempStr;
        } else {
          str = str + cnt + tempStr;
        }
        cnt = 1;
        tempStr = nextStr;
      }
    }
    if (cnt === 1) {
      str = str + tempStr;
    } else {
      str = str + cnt + tempStr;
    }

    answer = Math.min(answer, str.length);
  }
  return answer;
}

S로 문자열이 들어오게 된다. 이후에 같은 문자끼리 특정 단위수로 쪼개고 앞에 쪼갠 개수를 앞한 문자열과 총 문자열을 비교하기 위해 answer를 s의 길이로 정한다.

 

1단위씩 쪼개기 시작해서 문자열만큼 쪼개야하지만 문자열의 반까지만 단위를 쪼개어도 된다. 예를 들어 8자리문자열이라면 4단위로 쪼개면 4-4로 되고 5까지 쪼개면 5-3이니 5개문자열과 3개문자열은 절대 같지 않고 중복되는 문자열이 없다

 

for문에서 1부터 문자열의 반틈까지만큼만 쪼개기로 하고 기준점tempstr을 substr(0,i)로 잡아준다. i는 쪼갤 단위수이다.

두번째 for문에서 비교할 문자열을 nextstr로 잡아준다. idx 즉 인덱스 위치는 i 이고 i만큼씩 올려야하므로 idx+=i를 for문안에서 지정해준다.

 

기준점과 비교점이 같을시 cnt를 올리고 다를시 지금까지 쌓은 cnt+기준문자를 str에 저장시켜야한다. 여기서 이전에 쌓아놓은 cnt가 있을시 str+cnt+tempstr을 해주고 cnt가 없으면 지금까지 쌓은게 없고 바로 앞뒤가 다른 문자가 나왔다는것이다. 이럴시 str+tempstr을 해준다. 처리가 끝나면 cnt는 다시 1로 초기화해주고 기준점을 현재 비교점으로 바꾸어준다.

 

두번째 for문을 다돌고나면 나와서 첫번째 for문으로 돌아가기전 쌓아놓은 cnt가 있는지 확인해야한다. 왜냐면 두번째 for문 마지막 처리에서 계속 쌓이는걸로 끝이났다면 str 계산이 안됐을것이다. 그래서 cnt가 다시 1인지 검사한후 1이라면 마지막 기준점을 더해주고 아니라면 cnt에 마지막기준점을 더해서 합쳐준다.

첫번째 for문의 i가 1이며 1단위로 쪼갤시 마지막 a와 a가 같으니 if(tempStr ===nextStr)에 의해 cnt가 ++ 되고 두번째for문이 끝나게되면 str에 저장이되지않기 때문이다. 

 

또한 끝날때마다 첫번째 for문으로 돌아가기전 Math.min으로 answer과 우리가 쌓은 str의 길이중에 짧은것을 answer에 담아 다음 for문이 끝날때마다 비교해서 answer에 담아준 뒤 첫번째 for문도 끝이나면 answer을 리턴해주게 된다.

 

 

 

댓글