본문 바로가기

Dot Algo∙ DS/PS

[BOJ] 백준 3107번 IPv6 (Java)

    #3107 IPv6

    난이도 : 골드 5

    유형 : 문자열 / 정규식

     

    3107번: IPv6

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

    www.acmicpc.net

    ▸ 문제

    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의 축약되지 않은 형태를 출력한다.

     

    문제 풀이  

    주어진 IPv6의 주소를 생략된 부분을 모두 표기하여 전체 IPv6의 주소를 출력해주면 된다. 과정은 다음과 같다.

    1. "::" 0의 집합을 생략된 부분을 ":group:"으로 마킹한다.
    2. 주어진 전체 IPv6의 주소를 ":"를 기준으로 split한 다음 4자리보다 작은 수에는 "0"을 넣어 4자리로 채워준다.
      1. 여기서 empty는 무시한다. 이 부분은 "::"이 IPv6주소 맨 앞에 위치해 있을 경우 예외 처리이다.
    3. group이 포함되어있다면 생략된 group의 길이를 구해준다.  groupLen = 8 - fullIps.size() + 1;
    4. 4자리로 채워진 전체 IPv6의 주소를 배열에 입력받는다.
      1. "group"인 부분은 groupLen길이만큼 "0000"을 채워넣는다.
    5. 그렇게 저장한 전체 주소를 ":"로 다시 구분자를 넣어준다음 출력해준다.

     

    풀이 코드 

    import java.io.*;
    import java.util.*;
    import java.util.stream.*;
    
    public class IPv6 {
    
    	public static void main(String[] args) throws IOException{
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		String ipv6 = br.readLine();
    		if(ipv6.contains("::")) {
    			ipv6 = ipv6.replace("::", ":group:");
    		}
    		
    		List<String> ipv6s  = Stream.of(ipv6.split(":")).collect(Collectors.toList()); 
    		List<String> fullIps = new ArrayList<>();
    		for(int i=0; i<ipv6s.size(); i++) {
    			String s = ipv6s.get(i);
    			if(s.isEmpty()) continue;
    			while(s.length() <4) {
    				s = "0"+s;
    			}
    			fullIps.add(s);
    		}
    		
    		int groupLen = 8 - fullIps.size() + 1;
    		String[] ipFullAddresses = new String[8];
    		int idx = 0;
    		for(String ip : fullIps) {
    			if(ip.equals("group")) {
    				while(groupLen-- > 0) {
    					ipFullAddresses[idx++] = "0000";
    				}
    			}else {
    				ipFullAddresses[idx++] = ip;
    			}
    		}
    		System.out.println(String.join(":", ipFullAddresses));
    	}
    }