문제 : https://www.acmicpc.net/problem/2686

 

2686번: 팩스

팩스 머신은 run-length encoding(RLE)을 이용해 데이터를 압축한다. 데이터는 같은 값이 연속적으로 많이 나타나는 수열이라 할 수 있다. 이러한 연속적인 같은 값을 run이라 한다. 그래서 RLE는 그 수

www.acmicpc.net

 

문제 요약 : 해당 문자열을 인코딩하여 출력

 

JAVA

소스코드 : https://github.com/cbkpar/BOJ/blob/main/boj_2686.java

채점 번호 아이디 문제 번호 결과 메모리 시간 언어 코드 길이
34341636 cbkpar 2686 맞았습니다!! 22048KB 304ms Java 11 2947B
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        int p = Integer.parseInt(br.readLine());
        while (p-- > 0) {
            int b = Integer.parseInt(br.readLine());
            int cnt = 0;
            char[] ch = new char[b * 2];
            for (int i = 0; i < (b + 39) / 40; i++) {
                String str = br.readLine();
                int sz = str.length();
                for (int j = 0; j < sz; j++) ch[cnt++] = str.charAt(j);
            }
            int sz = 0;
            String ans = "";
            StringBuilder tsb = new StringBuilder();
            for (int i = 0; i < b; i++) {
                if (i + 2 < b) {
                    if ((ch[i * 2] == ch[i * 2 + 2]) && (ch[i * 2 + 1] == ch[i * 2 + 3]) && (ch[i * 2] == ch[i * 2 + 4]) && (ch[i * 2 + 1] == ch[i * 2 + 5])) {
                        if (sz != 0) {
                            ans = ans + numtoch(sz - 1) + tsb.toString();
                            tsb = new StringBuilder();
                        }
                        sz = 3;
                        while (true) {
                            if (i + sz >= b || sz == 130) break;
                            if (ch[i * 2] == ch[i * 2 + sz * 2] && ch[i * 2 + 1] == ch[i * 2 + sz * 2 + 1]) {
                                sz++;
                            } else {
                                break;
                            }
                        }
                        ans = ans + numtoch(sz + 125) + ch[i * 2] + ch[i * 2 + 1];
                        i += sz - 1;
                        sz = 0;
                        continue;
                    }
                }
                sz++;
                tsb.append(ch[i * 2] + "" + ch[i * 2 + 1]);
                if (sz == 128) {
                    ans = ans + numtoch(sz - 1) + tsb.toString();
                    sz = 0;
                    tsb = new StringBuilder();
                }
            }
            if (sz != 0) ans = ans + numtoch(sz - 1) + tsb.toString();
            sb.append(ans.length() / 2 + "\n");
            for (int i = 0; i < (ans.length() + 79) / 80; i++) {
                sb.append(ans.substring(i * 80, Math.min((i + 1) * 80, ans.length())) + "\n");
            }
        }
        System.out.println(sb);
    }

    private static String numtoch(int n) {
        int a = n / 16;
        int b = n % 16;
        char A = ' ';
        char B = ' ';
        if (a >= 10) {
            A = (char) ('A' + a - 10);
        } else {
            A = (char) ('0' + a);
        }
        if (b >= 10) {
            B = (char) ('A' + b - 10);
        } else {
            B = (char) ('0' + b);
        }
        return A + "" + B;
    }
}

우선 입력이 80개의 문자로 쪼개져서 들어오기 때문에

나누어진 문자열을 하나의 char[] 배열에 담아준다.

이때 문자는 2개가 하나의 글자를 나타내게 된다.

글자를 하나하나 씩 보며

 

A. 해당 글자가 다음 글자와 그다음 글자와 같을 경우

 저장된 글자의 크기(함수를 통해 변환)와 저장된 글자를 ans에 더해준다.

 해당 글자가 얼마나 길게 다음 글자와 같은지 계산한다

 계산 도중 같은 글자가 130자를 넘어갈 경우 종료한다.

 저장된 글자의 크기(함수를 통해 변환)와 해당 글자를 ans에 더해준다.

 

B. 해당 글자가 다음 글자와 그 다음글자와 다를경우, 다음글자 혹은 그다음 글자가 없을 경우

 해당 글자를 저장해준다.

 계산 도중 저장된 글자가 128자가 될 경우

 저장된 글자의 크기(함수를 통해 변환)와 해당 글자를 ans에 더해준다.

 

 

모든 글자를 확인 후 저장된 글자가 있을 경우

저장된 글자의 크기(함수를 통해 변환)와 해당 글자를 ans 에 더해준다.

마지막으로 80 글자씩 잘라주어 출력한다.

 

+ Recent posts