高度情報システム科 ブログ
最優秀賞者のプログラム精解!(その3)
2018.12.26
Javaプログラミングコンテスト最優秀賞者のプログラムを見てみよう、第3弾です。
残っている処理は、与えられたIPアドレスのブロードキャストアドレスを求めることです。
int型の変数ipには現在、IPアドレスが数値として入っています。またint型の変数zには、サブネットマスクのサフィックス値が入っています。
たとえばIPアドレスが192.168.61.145/26であるとき、ブロードキャストアドレスは上位26ビットはそのまま、残りの6ビットはすべて1にしたものになります。
では、最優秀者のコードを見ていきます。
前回の処理で既に
char[] ipc = Integer.toBinaryString(ip).toCharArray();
を実行しています。char型の配列ipcには、ipを2進数にしたものを1桁ずつ区切って0か1を文字にしたものが格納されています。
ネットワークアドレスのときは、
for (int i = 31; i >= z; i--) ipc[i] = '0';
としましたが、ブロードキャストアドレスのときは
for (int i = 31; i >= z; i--) ipc[i] = '1';
とします。
あとは表示するだけですが、これもネットワークアドレスのときと一緒。
a = b = c = d = 0;
for (int i = 0; i < 8; i++) {
a += (ipc[i] - '0') << (7 - i);
b += (ipc[i + 8] - '0') << (7 - i);
c += (ipc[i + 16] - '0') << (7 - i);
d += (ipc[i + 24] - '0') << (7 - i);
}
System.out.println(a + "." + b + "." + c + "." + d);
ちなみに、サブネットマスクとIPアドレスの論理積をとればネットワークアドレスが求まりますが、ブロードキャストアドレスの場合はサブネットマスクの0と1を反転したものとIPアドレスの論理和をとればよいです。
しかし今回のコードでは、あまり難しく考えずにシンプルに処理されていますね。
今回紹介したコードを繋げたものは以下のようになります。
String[] sp = str.split("[\\./]");
int a = Integer.parseInt(sp[0]);
int b = Integer.parseInt(sp[1]);
int c = Integer.parseInt(sp[2]);
int d = Integer.parseInt(sp[3]);
int z = Integer.parseInt(sp[4]);
int ip = (a << 24) + (b << 16) + (c << 8) + d;
char[] ipc = Integer.toBinaryString(ip).toCharArray();
for (int i = 31; i >= z; i--) ipc[i] = '0';
a = b = c = d = 0;
for (int i = 0; i < 8; i++) {
a += (ipc[i] - '0') << (7 - i);
b += (ipc[i + 8] - '0') << (7 - i);
c += (ipc[i + 16] - '0') << (7 - i);
d += (ipc[i + 24] - '0') << (7 - i);
}
System.out.println(a + "." + b + "." + c + "." + d);
for (int i = 31; i >= z; i--) ipc[i] = '1';
a = b = c = d = 0;
for (int i = 0; i < 8; i++) {
a += (ipc[i] - '0') << (7 - i);
b += (ipc[i + 8] - '0') << (7 - i);
c += (ipc[i + 16] - '0') << (7 - i);
d += (ipc[i + 24] - '0') << (7 - i);
}
System.out.println(a + "." + b + "." + c + "." + d);
とにかくコンテストの短い時間でここまで書けたのが驚きだったので、3回に分けて紹介しました!