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

seb Incode·2022년 5월 29일
0
post-thumbnail

문제 설명




풀이

크게 봤을 때, 자르자 -> 비교하자 -> (같은 문자열) 개수 세자 -> 압축하자 -> 문자열 비교해서 작은 거 찾자
이 로직이다.

자를 땐 1개씩 잘라보기 -> 2개씩 잘라보기 -> 3개씩 -> ... -> 문자열 절반길이씩 잘라보기를 위해 for문 (1)을 사용한다.

자르고 나선 무엇을 해야 하는가?

잘려진 부분 문자열 모두를 반복문으로 순회하면서 앞 혹은 뒤와 비교하면서 개수를 세면 된다.
나는 현재(i) 부분 문자열과 뒤에 있는(i+1)에 있는 부분 문자열과 비교했다.
이 때 i가 배열의 마지막 값인지 아닌지 판별해주어야 한다. (i+1) 때문에 인덱스 아웃 오븡 ㅓ 어쩌구 예외가 발생하기 때문❗

이런식으로 압축하고 나서 압축된 문자열 길이 확인하고 현 시점까지의 최소 길이와 비교해주면 된다.

압축하는 과정에서 개수 세는 과정이 이 문제의 핵심이었던 것 같다.

소스코드

import java.util.*;

class Solution {
    public int solution(String s) {
        int answer = 0;
        int minLen = s.length();    //최소 압출 길이 초기화
        int len = s.length();
        //1 자를 수 있는 모든 단위만큼 반복
        for(int i=1;i<=s.length()/2;i++){
            //배열 크기 확정 못하기 때문에 ArrayList로
           ArrayList<String> tokens = new ArrayList<>();
            
            //2-1 i단위만큼 문자열 token으로 나누기
            for(int j=0;j<len;j += i){
                if(j+i<len){
                    tokens.add(s.substring(j, j+i));
                }
                else{
                    tokens.add(s.substring(j));
                }
            }
            //System.out.println(tokens);
            String result ="";  //압축한 문자열 저장
            //2-2 부분 문자열 같은지 체크하고 압축 문자열 만드는 for문
                
            int cnt = 1;
            for(int z=0;z<tokens.size();z++){ 
                
                if(z < tokens.size()-1){    //마지막 토큰이 아닐 때
                    if(tokens.get(z).equals(tokens.get(z+1))){
                        cnt++;
                    }
                    else{
                        if(cnt==1){
                            result += tokens.get(z);    //앞과 다른 문자열이라 바로 저장

                        }
                        else{
                            result += cnt+""+tokens.get(z);    //앞에 상수 붙여서 문자열 저장  
                            cnt = 1;    //중복 개수 초기화
                        }
                    }
                }
                //마지막 토큰일 때는
                else{
                    if(cnt==1){
                            result += tokens.get(z);    //앞과 다른 문자열이라 바로 저장

                        }
                        else{
                            result += Integer.toString(cnt)+tokens.get(z);    //앞에 상수 붙여서 문자열 저장
                        }
                }
            }
            minLen = Math.min(minLen, result.length()); //더 작은 문자열 길이 찾기
        }
        answer = minLen;
        return answer;
    }
}

0개의 댓글