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

Yoon Uk·2022년 6월 21일
0
post-thumbnail

문제

[프로그래머스] 문자열 압축
https://programmers.co.kr/learn/courses/30/lessons/60057?language=java

풀이

  1. 압축할 문자열을 정한다.
  2. 압축한 문자열의 길이만큼 계속 탐색한다.
    • 다음 문자열과 압축할 문자열이 같으면 압축 갯수를 1씩 증가시킨다.
    • 같지 않으면 이전까지 탐색한 문자열의 갯수(zipLength)와 압축한 문자열을 붙인다.
  3. 압축 완료 된 문자열의 길이를 구해 최솟값을 구한다.
  • substring(i, j) 메소드는 문자열의 i번째 인덱스부터 j-1 인덱스까지를 슬라이싱 하는 메소드이다.
  • StringBuilder를 활용해 문자열을 계속 붙여나가며 압축된 문자열을 새로 생성한다.
  • 변수 zipStr은 압축할 문자이다. (e.g. "aa", "bb" 등)
  • 변수 zipLengthzipStr으로 비교했을 때 같은 문자열이 몇 개 인지를 나타낸다.
  • 새로운 문자열을 만들 때 zipLength가 1(즉, 압축이 되지 않음) 이라면 공백("")을 넣고 2 이상(즉, 압축이 됨) 이라면 zipLength(압축된 갯수)를 앞에 붙이고 뒤에 압축한 문자열을 붙인다.
  • 마지막 zipStr을 새로운 문자열에 붙인다.

코드

프로그래머스 제출

class Solution {
    public int solution(String s) {
        
        int answer = s.length();
		
		for(int i=1; i<=s.length()/2; i++) {
			int zipLength = 1;
			String zipStr = s.substring(0, i); // 압축할 문자(문자열의 0번째부터 i-1번째까지)
			StringBuilder sb = new StringBuilder(); // 압축 완료된 문자열을 붙이면서 새로 만들 문자열
			
			for(int j=i; j<=s.length(); j+=i) { // i, 즉 앞축할 문자열 길이 만큼 j를 증가시켜줌
				String nextStr = s.substring(j, (j + i > s.length()) ? s.length() : j + i); // 다음 문자열에 j부터 j+i-1까지, 근데 배열 끝 이상으로까지 넘어가면 그냥 그 문자열의 길이-1 만큼 넣음
				
				if(zipStr.equals(nextStr)) {
					zipLength++;//같으면 그냥 압축 갯수 +1
				} else {
					//다음 문자열이 반복되는(즉, 앞의)문자열과 다르면 
					sb.append((zipLength != 1 ? zipLength : "") + zipStr); // 압축이 안 됏으면 그냥 공백(""), 압축이 됏으면 압축된 갯수 넣고 뒤에 그 압축문자열 단위 바로 붙임
					zipStr = nextStr;//방금 붙인 문자열을 새로운 압축 문자열로 등록해줌
					zipLength = 1; // 앞의 문자열과 달랏으니깐 새로운 압축갯수로 초기화 해 줌
				}
			}
			
			sb.append(zipStr); // 마지막꺼는 안붙여줫으니깐 여기서 붙여줌
			
			answer = Math.min(answer, sb.length()); // 최소값 찾음
		}
        
        return answer;
    }
}

이클립스로 확인

public class Programmers {

	public static void main(String[] args) {
		
		String s = "ababcdcdababcdcd";
		

		int answer = s.length();
		
		for(int i=1; i<=s.length()/2; i++) {
			int zipLength = 1;
			String zipStr = s.substring(0, i); // 압축할 문자(문자열의 0번째부터 i-1번째까지)
			StringBuilder sb = new StringBuilder(); // 압축 완료된 문자열을 붙이면서 새로 만들 문자열
			
			for(int j=i; j<=s.length(); j+=i) { // i, 즉 앞축할 문자열 길이 만큼 j를 증가시켜줌
				String nextStr = s.substring(j, (j + i > s.length()) ? s.length() : j + i); // 다음 문자열에 j부터 j+i-1까지, 근데 배열 끝 이상으로까지 넘어가면 그냥 그 문자열의 길이-1 만큼 넣음
				
				if(zipStr.equals(nextStr)) {
					zipLength++;//같으면 그냥 압축 갯수 +1
				} else {
					//다음 문자열이 반복되는(즉, 앞의)문자열과 다르면 
					sb.append((zipLength != 1 ? zipLength : "") + zipStr); // 압축이 안 됏으면 그냥 공백(""), 압축이 됏으면 압축된 갯수 넣고 뒤에 그 압축문자열 단위 바로 붙임
					zipStr = nextStr;//방금 붙인 문자열을 새로운 압축 문자열로 등록해줌
					zipLength = 1; // 앞의 문자열과 달랏으니깐 새로운 압축갯수로 초기화 해 줌
				}
			}
			
			sb.append(zipStr); // 마지막꺼는 안붙여줫으니깐 여기서 붙여줌
			
			answer = Math.min(answer, sb.length()); // 최소값 찾음
		}
		
		
		System.out.println(answer);
	}

}

정리

  • 문자열을 압축하고 탐색해야 한다는 생각은 떠올랐지만 코드로 구현하는 것이 어려웠다.
  • if문 대신 삼항연산자를 사용하여 코드를 간결하게 작성할 수 있었다.

0개의 댓글