[백준] PS/Java
[백준 2064] IP 주소 - JAVA
SH3542
2025. 5. 9. 23:40
https://www.acmicpc.net/problem/2064
1.
String[] ipByte = br.readLine().split("\\.");
regex에서 "."은 임의의 한 문자를 의미한다. 따라서, 모든 문자를 구분자로 사용하므로 빈 배열이 생성된다.
마침표 자체를 표시하기 위해 이스케이프 두 번 처리해준다.
2.
%32s : 왼쪽에 32 - s.len 만큼 공백 채움
%-32s : 오른쪽에 32 - s.len 만큼 공백 채움
항상 bit에서 0을 채워야하면 왼쪽이여서 몰랐었다. 해당 문제는 -를 붙여서 오른쪽을 채운다.
또한, 찾아보니 %S는 string을 uppercase로 표시해준다. %D는 없고 UnknownFormatConversionException을 던진다고 한다.
3.
32-m에서 m이 0이면, 2^32로 signed int 범위를 벗어난다.
해당 케이스가 있는진 확인 안했는데 long으로 쓰는게 낫다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
// i번째 ip 주소의 j번 째 byte 값
int[][] ip = new int[N][4];
for (int i = 0; i < N; i++) {
String[] ipByte = br.readLine().split("\\.");
for (int j = 0; j < 4; j++) {
ip[i][j] = Integer.parseInt(ipByte[j]);
}
}
for (int m = 0; m < 33; m++) {
int maskBits = 32 - m;
// 네트워크 마스크 : 32 - m번째 까지 1을 채움 , 나머지는 0
String mask = String.format("%-32s", Long.toBinaryString((1L << maskBits) - 1))
.replace(" ", "0");
// 네트워크 마스크를 byte 단위로 분리
int[] maskByte = new int[4];
int st = 0;
for (int i = 0; i < 4; i++, st += 8) {
maskByte[i] = Integer.parseInt(mask.substring(st, st + 8), 2);
}
boolean isAns = true;
// 네트워크 주소 : 첫 ip 주소를 대표로, 네트워크 마스크와 & 연산한 값
int[] adrByte = new int[4];
for (int i = 0; i < 4; i++) {
adrByte[i] = maskByte[i] & ip[0][i];
}
// 같은 네트워크(답)려면, 다른 모든 ip 주소에 대해서도 & 연산한 값이 같아야 함.
for (int i = 1; i < N; i++) {
for (int j = 0; j < 4; j++) {
if ((maskByte[j] & ip[i][j]) != adrByte[j]) {
isAns = false;
}
}
}
if (isAns) {
System.out.println(String.format("%d.%d.%d.%d",
adrByte[0], adrByte[1], adrByte[2], adrByte[3]));
System.out.println(String.format("%d.%d.%d.%d",
maskByte[0], maskByte[1], maskByte[2], maskByte[3]));
break;
}
}
}
}