알고리즘/구현

프로그래머스 - 문자열 압축

제이G 2022. 6. 30. 03:43

 


 

풀이

 

 


코드

import java.util.*;
class Solution {
    public int solution(String s) {
        StringBuilder sb = new StringBuilder();
        int count = 0;
        //step0: 압축길이 설정
        for (int zip=1; zip<=s.length()/2; zip++) {
            
            //step1: 타겟문자열생성
            for (int targetIdx=0; targetIdx<=s.length() - 2*zip; targetIdx+=count*zip) {
                count = 1;
                String target = s.substring(targetIdx, targetIdx+zip);
                // System.out.println("target: " + target);
                
                //step2: 비교문자열생성
                for (int compareIdx=targetIdx+zip; compareIdx+zip<=s.length(); compareIdx+=zip) {
                    String compare = s.substring(compareIdx, compareIdx+zip);
                    // System.out.println("compare: " + compareIdx + ": " + compare);
                    //타겟==비교 -> 중복count 증가, 다음비교 진행
                    if (compare.equals(target)) {
                        count++;
                        continue;
                    }
                    //타겟!=비교 -> 현타겟에 대한 비교종료
                    else {
                        break;
                    }
                }
                //현타겟에 대한 비교검출이 끝났으니, 기록을 해야할 것
                //중복이 존재한다면, 중복개수 + 타겟 기록
                if (count > 1) sb.append(count+target);
                //중복이 없다면, 타겟만 기록
                else sb.append(target);
                
                /**다음타겟을 만들수 없으면 나머지 문자열에 대해 기록해야함
                하지만, 로직상 step1의 for문이 조건식에의해 스킵되기 때문에
                step1의 for문으로 들어가기 전에 nextTargetIdx에 대해 조사 후
                조건식을 넘어버리면 즉, 다음타겟생성이 불가하면 나머지 문자열에
                대해 기록해줘야 함.**/
                int nextTargetIdx = targetIdx+count*zip;
                if (nextTargetIdx > s.length() - 2*zip) sb.append(s.substring(nextTargetIdx, s.length()));
            }
            sb.append("\n");
        }
        // System.out.println(sb);
        String[] result = sb.toString().split("\n");
        int answer = s.length();
        for (int i=0; i<result.length; i++) {
            answer = Math.min(result[i].length(), answer);
        }
        if (s.length() == 1) answer = 1;
        return answer;
    }
}

 

 


핵심

1. for문의 조건식, 증감식에 사용하는 변수에 대해 for문 내부에서 별도의 값변형이 발생하는 것은 지양하자.

ex)

for (int i=0; i<N; i++) {

if ~~ { i += 1; }

else if ~~ { i -= 1; }

...

}

--> 이런식의 코딩은 예상치못한 i값으로 인해 정답률이 낮아지고 디버깅도 매우 힘들어짐을 경험함

 

2. for문의 조건식, 증감식에 사용하는 변수는 의미에 맞게 명확히 선언하자.

ex)

for (int i=0; i<N; i++) --> 해당 for문이 무엇을 하기위한 for문인지 한눈에 식별이 어려움

for (int targetIdx=0; targetIdx<N; targetIdx++) --> 해당 for문은 타겟을 생성하기위한 for문임을 명확히 알 수 있음

 

3. 문제에 대한 설계가 끝났으면 증류해서 문제의 로직을 간략화해서 접근하자.

 

4. Edge Case에 대해 항상 생각하자.