这是2020年3月25日华为笔试第一题
问题描述
输入两个IP地址和合法的子网掩码,如
192.168.1.1 192.168.1.2 255.255.255.0
输出结果1表示IP1,IP2在同一子网,并输出IP1的网络号
1 192.168.1.0
192.168.21.156 192.168.45.148 255.255.255.128
0表示IP1,IP2不在同一子网并输出IP1的网络号
0 192.168.21.128
判断IP和IP2是否为同一个子网我的思路是
1、将三部分地址按空格截取(string.spilt(" “));
2、将每个地址按(”\.")截取;
3、将每部分转换为二进制连接成完整的IP地址二进制字符串。另外 两个也执行同样的操作;
4、将子网掩码的1的部分统计数量
5、根据子网掩码的结构截取IP1、IP2的有效部分,并判断是否相同,从而判断IP和IP2是否在同一个字段
输出IP1的网络号我的思路是:
1、将刚才截取的IP1的部分补全为32位;
2、将1中补全的字符串按每八位截取;
3、按将每部分取字符(1或0)根据位置变为十进制,并累加为256进制的标准IP;
4、将四部分用点字符串连接输出;
代码缺陷
该程序输入必须为IP1 IP2 子网掩码
输入的子网掩码应该是和IP1相匹配
@wahaha13168
https://blog.csdn.net/wahaha13168/article/details/83008252?utm_source=blogxgwz8
代码
import java.io.IOException;
public class Zyy{
public static void main(String[] args) throws IOException {
byte [] a = new byte[200]; //用来保存键盘的输入
String [] bin = new String[100]; //保存IP地址转成的二进制字符串
int len = System.in.read(a); //键盘键入的字符的长度
String string = new String(a,0,len -2); //将键盘键入的字符转化为字符串,并把换行和光标移到行首的两个字符去掉
String [] ch = string.split(" ");//按空格截取,将IP1,iP2 和子网掩码nm 分别截取到ch数组
String [] ip1 = ch[0].split("\\.");//按'.'截取,通过\转义\,在通过\转义'.',将IP1的每个部分截取保存到IP1的数组中
String [] ip2 = ch[1].split("\\.");//同上
String [] nm = ch[2].split("\\."); //同上
// System.out.println(ip1[0]);
// System.out.println(ip1[1]);
// System.out.println(ip1[2]);
// System.out.println(ip1[3]);
//将IP1的地址转换为二进制
for (int i = 0; i < ip1.length; i++) {
int temp = Integer.parseInt(ip1[i]);//将字符串转换为int型数据
if(bin[0] == null) { //字符串为空
bin[0] =toBinary(temp , 8); //将转换的二进制字符串直赋值给bin[0];toBinary将int数据转换为二进制的函数
} else {
bin[0] = bin[0] + toBinary(temp , 8);//不为空,将字符串连接
}
}
//将iP2的地址转为二进制字符串
for (int i = 0; i < ip1.length; i++) {
int temp = Integer.parseInt(ip2[i]);
if(bin[1] == null) {
bin[1] =toBinary(temp , 8);
} else {
bin[1] = bin[1] + toBinary(temp , 8);
}
}
//将子网掩码转换为二进制
for (int i = 0; i < ip1.length; i++) {
int temp = Integer.parseInt(nm[i]);
if(bin[2] == null) {
bin[2] =toBinary(temp , 8);
} else {
bin[2] = bin[2] + toBinary(temp , 8);
}
}
// System.out.println(bin[0]);
// System.out.println(bin[1]);
// System.out.println(bin[2]);
//判断子网掩码的结构,即什么时候有1变0,统计个数
int count = 0;
for(int i =0 ;i <bin[2].length();i++) {
char ch1 = bin[2].charAt(i);
if(ch1 == '1') {
count++;
} else {
break ;
}
}
//将IP1的IP2按照子网掩码的结构截取
String yip1 = bin[0].substring(0, count);
// System.out.println(yip1);
String yip2 = bin[1].substring(0, count);
// System.out.println(yip2);
int result = 0; //定义两个IP是否在同一子网的标志位
if(yip1.equals(yip2)) { //字符串比较,若相同在同一子网
result = 1; //将标志位置为1
}
System.out.println(result); //输出结果
//2、输出子网1的网络号
while(yip1.length() != 32) { //将刚才截取的IP1补全为32地址
yip1 = yip1 + "0";
}
String [] yipa = new String[4]; //保存截取的IP1的网络号的每个部分
yipa[0] = yip1.substring(0,8);//按八位截取为四部分
yipa[1] = yip1.substring(8,16);
// System.out.println(yipa[1]);
yipa[2] = yip1.substring(16,24);
// System.out.println(yipa[2]);
yipa[3] = yip1.substring(24,32);
// System.out.println(yipa[3]);
int ipz[] = new int [4]; //申请int数组保存二进制转为的256进制数
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 8; j++) {
char q = yipa[i].charAt(j);//按位取字符
// System.out.println(q);
if(q == '1') { //若为1,则根据转换规则将所有位的结果相加就是最终的网络号的值
ipz[i] = (int) (ipz[i] + 1 * Math.pow(2, (7-j)));
// System.out.println(ipz[i]);
}
}
}
// System.out.println(ipz[0]);
// System.out.println(ipz[1]);
// System.out.println(ipz[2]);
// System.out.println(ipz[3]);
System.out.println(ipz[0]+"."+ipz[1]+"."+ipz[2]+"."+ipz[3]);//将每个位置的数据和‘.’连接起来就得到了IP1的网络号
}
/**
* 将一个int数字转换为二进制的字符串形式。
* @param num 需要转换的int类型数据
* @param digits 要转换的二进制位数,位数不足则在前面补0
* @return 二进制的字符串形式
* /https://blog.csdn.net/wahaha13168/article/details/83008252?utm_source=blogxgwz8
*/
public static String toBinary(int num, int digits) {
int value = 1 << digits | num;
String bs = Integer.toBinaryString(value); //0x20 | 这个是为了保证这个string长度是6位数
return bs.substring(1);
}
}
结果展示
1、IP1和IP2在同一子网
2、IP1和IP2不在同一子网