알고리즘/[ Baekjoon ]

[ BOJ ][JAVA][3107] IPv6

kim.svadoz 2021. 11. 3. 17:23
반응형

https://www.acmicpc.net/problem/3107

 

3107번: IPv6

첫째 줄에 올바른 IPv6 주소가 주어진다. 이 주소는 최대 39글자이다. 또한, 주소는 숫자 0-9, 알파벳 소문자 a-f, 콜론 :으로만 이루어져 있다.

www.acmicpc.net

시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 128 MB 1517 423 365 35.334%

문제

IPv6은 길이가 128비트인 차세대 인터넷 프로토콜이다.

IPv6의 주소는 32자리의 16진수를 4자리씩 끊어 나타낸다. 이때, 각 그룹은 콜론 (:)으로 구분해서 나타낸다.

예를 들면, 다음과 같다.

2001:0db8:85a3:0000:0000:8a2e:0370:7334

32자리의 16진수는 사람이 읽고 쓰기에 불편하고, 대부분의 자리가 0이기 때문에 아래와 같이 축약할 수 있다.

  1. 각 그룹의 앞자리의 0의 전체 또는 일부를 생략 할 수 있다. 위의 IPv6을 축약하면, 다음과 같다
2001:db8:85a3:0:00:8a2e:370:7334
  1. 만약 0으로만 이루어져 있는 그룹이 있을 경우 그 중 한 개 이상 연속된 그룹을 하나 골라 콜론 2개(::)로 바꿀 수 있다.
2001:db8:85a3::8a2e:370:7334

2번째 규칙은 모호함을 방지하기 위해서 오직 한 번만 사용할 수 있다.

올바른 축약형 IPv6주소가 주어졌을 때, 이를 원래 IPv6 (32자리의 16진수)로 복원하는 프로그램을 작성하시오.

입력

첫째 줄에 올바른 IPv6 주소가 주어진다. 이 주소는 최대 39글자이다. 또한, 주소는 숫자 0-9, 알파벳 소문자 a-f, 콜론 :으로만 이루어져 있다.

출력

첫째 줄에, 입력으로 주어진 IPv6의 축약되지 않은 형태를 출력한다.

예제 입력 1

25:09:1985:aa:091:4846:374:bb

예제 출력 1

0025:0009:1985:00aa:0091:4846:0374:00bb

예제 입력 2

::1

예제 출력 2

0000:0000:0000:0000:0000:0000:0000:0001

접근

특정 알고리즘(?)은 떠오르지 않았고, 말그대로 구현문제였다.

:: 은 딱 한번 나온다는 것을 고려해 해당 인덱스를 따로 저장하였고, 첫 번째 규칙을 적용한 다음 두 번째 규칙을 적용하는 식으로 풀어 갔다.

개선할 점은 재사용 코드를 조금 더 잘 모듈화 할 수 있을 것 같고, 덜 지저분하게 풀 수 있을 것 같다. 그리고 String객체를 추가로 만들지 않고, StringBuilder에 insert() 메서드를 쓰면 더 가독성과 메모리효율이 좋지 않았을까 싶다.

코드

/**
 * BOJ 3107 IPv6
 * 문자열, 구현
 */
import java.io.*;
import java.util.*;

public class p3107 {
    static String s;
    static Queue<Character> q;
    static StringBuilder sb;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        s = br.readLine();

        q = new LinkedList<>();
        sb = new StringBuilder();
        boolean flag = false;
        boolean temp = false;
        int part = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ':') {
                if (!temp) {
                    part++;
                }
                if (flag) {
                    temp = true;
                    continue;
                }
                // 이전꺼까지 확실하게 맞춰야한다.
                make4length();

                sb.append(c);
                flag = true;
            } else {
                q.add(c);
                flag = false;
            }
        }
        make4length();

        int idx = (part - 1) * 4 + part - 1;
        String left = sb.substring(0, idx);
        String right = sb.substring(idx, sb.length());

        StringBuilder tmp = new StringBuilder();
        int check = sb.length();
        while (check < 39) {
            int zero = 0;
            zero++;
            while (zero < 5) {
                tmp.append("0");
                check++;
                zero++;
            }
            tmp.append(":");
            check++;
        }
        String answer = left + tmp.toString() + right;

        System.out.println(answer);
    }

    static void make4length() {
        int zero = 0;
        while (q.size() + zero < 4) {
            sb.append("0");
            zero++;
        }
        while (!q.isEmpty()) {
            sb.append(q.poll());
        }
    }
}
반응형

'알고리즘 > [ Baekjoon ]' 카테고리의 다른 글

[ BOJ ][JAVA][2824] 최대공약수  (0) 2021.11.04
[ BOJ ][JAVA][3067] Coins  (0) 2021.11.04
[ BOJ ][JAVA][1477] 휴게소 세우기  (0) 2021.11.03
[ BOJ ][JAVA][3190] 뱀  (0) 2021.11.02
[ BOJ ][JAVA][1504] 특정한 최단경로  (0) 2021.11.02