Dazzling 개발 노트

[백준] 3107 - IPv6 (Java) 본문

Algorithm/백준

[백준] 3107 - IPv6 (Java)

dj._.dazzling 2023. 7. 3. 15:56

문제

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

 

3107번: IPv6

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

www.acmicpc.net

풀이 

첫번째 풀이

난 이차원 배열을 이용해서 풀었음.

입력받은 문자열을 이차원배열에서 임시 저장 후 출력은 StringBuilder를 이용함.

::로 생략된 경우 어느 위치, 얼만큼 생략됐는지 판단하는 부분이 어려웠던 것 같음.

일단 :: 부분은 :zero:로 대체하고 length를 이용해 몇 개가 생략되는지 판단함.

(근데 length 하나만으로는 판단할 수 없음 ㅎㅎ; 그치만 반복문2에서 대체가 가능함.)

zero를 만나면 "0000"으로 채워주는데, 만약 반복문1에서 채워지지 않아도 반복문2에서 0000이 채워짐.

두번째 풀이

처음 입력을 받은 후 split하여 배열로 만드는 것까지는 동일.

근데 이차원 배열은 이용하지 않고 배열 하나하나 비교함.

만약 입력받은 문자열 배열의 크기가 8보다 작다면 생략된 주소이므로 part를 이용해 현재 주소 길이를 파악함.

idx는 입력받은 문자열의 인덱스이고, cnt는 완성해야하는 전체 문자열의 인덱스

만약 tmp의 길이가 0이고 part가 8보다 작다면 비어있는 칸이므로 0000으로 채워줌.

tmp의 길이가 0보다 크다면 그 부분에 주소가 존재하므로 sb에 넣어주는데,

앞에 빈칸은 0으로 먼저 채운 후 나머지 문자열을 추가함.

idx로 입력받은 문자열에서 어디까지 0000으로 채우고, 어디부터 입력받은 문자열에서 가져올지 판단함.

**해당 방법을 java로 구현 시 ::가 마지막에 오는 경우도 고려 필요 (ex. 3::)

코드

첫번째 풀이 코드

package Implementation;

import java.io.*;

public class Problem3107_new {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		char arr[][] = new char[8][4];
		
		String ip = br.readLine();
		if (ip.contains("::")) {
			ip = ip.replace("::", ":zero:");
		}
		
		String[] arrStr = ip.split(":");
		
		int length = 8 - arrStr.length;
		
		
		
		// 반복문1
		for (int i=0, j=0; i<8; i++, j++) {
			if (arrStr[j].equals("zero")) {
				for (int k=i; k<i+length+1; k++) {
					arr[k] = "0000".toCharArray();
				}
				i += length ;
			} else {
				arr[i] = arrStr[j].toCharArray();
			}
		}
		
        // 반복문2
		for (int i=0; i<8; i++) {
			int tempLen = arr[i].length;
			if (tempLen != 4) {
				for (int k=0; k<4-tempLen; k++) {
					sb.append(0);
				}
				int ind = 0;
				for (int j=4-tempLen; j<4; j++, ind++) {
					sb.append(arr[i][ind]);
				}
			} else {
				sb.append(arr[i]);
			}
			
			if (i != 7) sb.append(":");
		}
		
		System.out.println(sb);
		
	}
}

두번째 풀이 코드

package Implementation;

import java.io.*;

public class Problem3107 {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		
		String ip = br.readLine();
		String[] arrStr = ip.split(":");
		
		int part = arrStr.length;
		for (String tmp : arrStr) {
            if(tmp.length() == 0) part--;
        }
		
		int idx = 0;	// 입력받은 문자열을 split한 배열의 index
		int cnt = 0;
		
		while ( idx < arrStr.length ) {
			String tmp = arrStr[idx];
			if (tmp.length() == 0 && part < 8) {	// ::로 인해 생략된 부분
				sb.append("0000");
				cnt++;
				part++;		// 빈 구역이 있는지 확인하기 위해 필요
			} else if (tmp.length() == 0) {
				idx++;
				continue;
			} else {
				int tempLen = 4 - tmp.length();
				for (int j=0; j<tempLen; j++) {
					sb.append("0");
				}
				sb.append(tmp);
				idx++; cnt++;
			}
			if (cnt < 8) sb.append(":");
		}
		
		while (cnt < 8) {
			sb.append("0000");
			cnt++;
			if (cnt < 8) sb.append(":");
		}
		
		System.out.println(sb);
		
	}
}

후기

특별한 방식이 필요한 알고리즘은 아니었다.

구현 문제라서 그냥 효율적으로 원하는 결과를 뽑으면 되는 형식이었음.

난 일단 굉장히 오랜 시간을 투자하여 풀었다. 2시간 ~ 3시간 정도.

근데 푼 것도 코드 보면 굉장히 지저분하고 딱 봐도 비효율적임 ㅋㅋㅋㅋㅋㅋㅋ 헤헷

그래도 풀어낸 것에 만족하고,, 뿌듯한 마음이다ㅠㅠ

언젠간 쉽게쉽게 풀어내는 고수가 될 수 있길!

Commit

https://github.com/allrightDJ0108/CodingTestStudy/commit/d4c129a7ba0e6fce09bfd17ab7e37418786a195b

참고

https://peace-log.tistory.com/m/entry/%EB%B0%B1%EC%A4%80-3107%EB%B2%88-IPv6-%ED%92%80%EC%96%B4%EB%B3%B4%EA%B8%B0-Java