ip相关Java题_程序员的算法趣题:Q40 优雅的IP地址(Java版)

前提知识

IPv4:32bit(二进制形式)或 192.168.1.2(十进制形式)

题目链接(力扣网):https://leetcode-cn.com/leetbook/read/interesting-algorithm-puzzles-for-programmers/9i00p1/

题目要求

1.二进制形式:左右对称,比如11111111000000000000000011111111

2.十进制形式:0~9均出现,且不重复

求:有多少个IP符合要求

思路一

左侧共16bit,即16个二进制位,共有65536种情况。

1.遍历0~65535的每个数字,将十进制转为二进制,记为字符串a

2.将字符串a反转,记为字符串b

3.将字符串a和b每8位切一段,共四段

4.将四段二进制形式的字符串逐一转为十进制,得到十进制数A,B,C,D

5.封装方法判断字符串A+B+C+D中是否完整出现0~9且不重复,满足即为正确答案之一

代码

public static void main(String[] args) {

Listlist = new ArrayList();

for(int i = 0; i < 65536; i ++){

String a = to2(i); // 自定义的方法to2:十进制 ==> 二进制格式

String b = new StringBuilder(a).reverse().toString(); // 反转

// 将二进制数据解析成十进制

int A = Integer.parseInt(a.substring(0,8), 2); // [AAAAAAAA --------]

int B = Integer.parseInt(a.substring(8,16), 2); // [-------- BBBBBBBB]

int C = Integer.parseInt(b.substring(0,8), 2); // [CCCCCCCC --------]

int D = Integer.parseInt(b.substring(8,16), 2); // [-------- DDDDDDDD]

String target = ""+A+B+C+D;

if(isUnique(target) && target.length() == 10){ // 自定义的方法isUnique

list.add(A + "." + B + "." + C + "." + D);

}

}

System.out.println(list);

}

// 十进制 => 16bit 的二进制形式

public static String to2(int num){

StringBuilder sb = new StringBuilder();

while(num > 0){

sb.insert(0,""+num % 2);

num /= 2;

}

while(sb.length() < 16){

sb.insert(0, "0");

}

return sb.toString();

}

// 判断字符串中是否每个字符都唯一

public static boolean isUnique(String s){

char[] cs = s.toCharArray();

Arrays.sort(cs);

for(int i = 0; i+1 < cs.length; i ++){

if(cs[i] == cs[i+1]) return false;

}

return true;

}

思路二

从思路一可以看出:

A.B.C.D四个数字,

只要A和D的二进制对称,B和C的二进制对称即可。

然后AD在外,BC在内,有4种组合;

然后BC在外,AD在内,有4种组合。

所以只需要求出有几个可用组合,然后乘以8,就可以得到优雅IP的数量了。

代码

public static void main(String[] args) {

// Step 1: 找出符合对称关系的A,B,C,D候选项

Listlist = new ArrayList(); // 下标(0,1) (2,3) (4,5)... (偶,奇)为一对。

for(int i = 0; i < 256; i ++){ // 只需遍历8bit的所有情况即可,所以256次循环即可

String a = to2(i); // 8bit,形如11110000

String b = new StringBuilder(a).reverse().toString(); // 8bit,形如00001111

if(! list.contains(i) && ! a.equals(b)){ // 避免添加重复的元素

list.add(i);

list.add(Integer.parseInt(b, 2)); // 将二进制的字符串b转为十进制数据

}

}

System.out.println(list);

// Step 2: 两对两对的组合,筛选出0~9全出现的组合(两对,4个数字)

ListresList = new ArrayList<>();

for(int i = 0; i+1 < list.size(); i += 2){ // 两个是一对,所以 i+=2

for(int j = i+2; j+1 < list.size(); j += 2){

int A = list.get(i);

int B = list.get(i+1);

int C = list.get(j);

int D = list.get(j+1);

String target = ""+A+B+C+D;

if(isUnique(target) && target.length() == 10){ // 是否0~9全出现(字符串长度为10)且不重复(isUnique返回true)

resList.add("{"+A+":"+B+","+C+":"+D+"}"); // 此处随便拼接成自己喜欢的格式,保证可读性即可

}

}

}

System.out.println("可用组合:"+resList); // 形如:[{34:68,179:205}],表示34和68是一对,179和205是一对。可以拼成34.179.205.68这样的优雅IP

}

public static String to2(int num){

StringBuilder sb = new StringBuilder();

while(num > 0){

sb.insert(0,""+num % 2);

num /= 2;

}

while(sb.length() < 8){ // 长度改为8

sb.insert(0, "0");

}

return sb.toString();

}

答案

34.179.205.68

34.205.179.68

68.179.205.34

68.205.179.34

179.34.68.205

179.68.34.205

205.34.68.179

205.68.34.179

8种

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值