문제 요약
IPv6은 길이가 128비트인 차세대 인터넷 프로토콜이다.
IPv6의 주소는 32자리의 16진수를 4자리씩 끊어 나타낸다. 이때, 각 그룹은 콜론 (:)으로 구분해서 나타낸다.
예를 들면, 다음과 같다.
2001:0db8:85a3:0000:0000:8a2e:0370:7334
32자리의 16진수는 사람이 읽고 쓰기에 불편하고, 대부분의 자리가 0이기 때문에 아래와 같이 축약할 수 있다.
각 그룹의 앞자리의 0의 전체 또는 일부를 생략 할 수 있다. 위의 IPv6을 축약하면, 다음과 같다
2001:db8:85a3:0:00:8a2e:370:7334
만약 0으로만 이루어져 있는 그룹이 있을 경우 그 중 한 개 이상 연속된 그룹을 하나 골라 콜론 2개(::)로 바꿀 수 있다.
2001:db8:85a3::8a2e:370:7334
2번째 규칙은 모호함을 방지하기 위해서 오직 한 번만 사용할 수 있다.
올바른 축약형 IPv6주소가 주어졌을 때, 이를 원래 IPv6 (32자리의 16진수)로 복원하는 프로그램을 작성하시오.
문제 분석
- IPv6 주소를 ":"으로 나누어 각 문자열을 리스트에 저장한다.
- 각 문자열의 길이에 따라 "0"을 앞에 추가하여 다시저장한다.
- "::"이 나올 때의 세 가지 경우를 고려하여 주소를 변환한다.
- "::"이 맨 앞에 있는 경우: "::1234:5678"
- 맨 앞의 "::"을 처리하고, 나머지 문자열의 개수를 세어서 필요한 만큼 "0000"를 삽입한다.
- "::"이 중간에 있는 경우: "1234::5678"
- "::"을 기준으로 리스트를 나누고, 각 부분의 문자열을 조합하여 완전한 주소를 삽입한다..
- "::"이 맨 뒤에 있는 경우: "1234:5678::"
- 맨 뒤의 "::"을 처리하고, 나머지 문자열의 개수를 세어서 필요한 만큼 "0000" 문자열을 삽입한다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
static String[] zeroString = {"","0","00","000","0000"};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
List<String> list = new ArrayList<>();
StringBuilder sb = new StringBuilder();
// split으로 나누면 ::의 경우 빈칸으로 나온다.
for(String s : br.readLine().split(":")){
if(!s.equals("")){
s = zeroString[4-s.length()] + s;
}
list.add(s);
}
// System.out.println(list);
if(list.size() == 0){
System.out.println("0000:0000:0000:0000:0000:0000:0000:0000");
return;
}
int coloneIdx = -1;
coloneIdx = list.indexOf("");
if(list.size() == 8 && coloneIdx == -1){
System.out.println(makeFullIpAdd(list, sb));
return;
}
// ::가 맨 앞에있을때(list의 맨 앞이 ""임)
// ::1
//[, , 0001]
if(list.get(0).equals("")){
// System.out.println("::가 맨 앞에있을때");
list.remove(coloneIdx);
while(list.size() <= 8){
list.add(coloneIdx, zeroString[4]);
}
}
// ::가 맨 뒤에있을때(colon값의 변도잉 없지만 list.size가 8이 아님)
// 1::
//[0001]
else if(list.size() != 8 && coloneIdx == -1){
// System.out.println("::가 맨 뒤에있을때");
while(list.size() < 8){
list.add(zeroString[4]);
}
}
// ::가 중간에 있을때
else{
while(list.size() <= 8){
list.add(coloneIdx, zeroString[4]);
}
}
System.out.println(makeFullIpAdd(list, sb));
}
private static String makeFullIpAdd(List<String> list, StringBuilder sb) {
for(int i = 0; i < list.size(); i++){
if(!list.get(i).equals("")){
sb.append(list.get(i));
if(i != list.size()-1){
sb.append(":");
}
}
}
return sb.toString();
}
}
정리
개선할 점
문제의 조건분기를 설정하고 해결하는데 시간이 오래 걸렸다. 좀 더 분석적으로 접근할 필요성이 있다.
'알고리즘 풀이 > 백준' 카테고리의 다른 글
[Gold V] 주사위 쌓기 - 2116 (Java) (0) | 2023.08.27 |
---|---|
[Silver II] 원숭이 매달기 - 2716 (Java) (0) | 2023.08.22 |
[Gold IV] 알고스팟 - 1261 (Java) (0) | 2023.08.19 |
[Gold V] 빗물 - 14719 (Java) (1) | 2023.08.08 |
[Gold IV] 가르침 - 1062 (Java) (1) | 2023.08.08 |