牛客网-华为机试-HJ33 整数与IP地址间的转换-详细代码和注释

HJ33 整数与IP地址间的转换
描述
原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
举例:一个ip地址为10.0.3.193
每段数字 相对应的二进制数
10 00001010
0 00000000
3 00000011
193 11000001

组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。

数据范围:保证输入的是合法的 IP 序列

输入描述:
输入
1 输入IP地址
2 输入10进制型的IP地址

输出描述:
输出
1 输出转换成10进制的IP地址
2 输出转换后的IP地址

示例1

输入:

10.0.3.193
167969729

输出:

167773121
10.3.3.193

参考代码和详细注释及解题思路,每个函数就是解题的整体思路:

package com.lqs;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * @Author lqs
 * @Date 2022年05月19日 10:12:04
 * @Version 1.0.0
 * @ClassName ms
 * @Describe 注意:
 * 在代码中定义整数型时,全部使用long型,防止int存储不下
 */
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        //读取IP地址,并按照点进行切分
        String[] split = input.nextLine().split("\\.");
//        int parseInt = Integer.parseInt(input.nextLine());//超过int型存储范围的数装不下,故用long类型
        //读取需要转换的整数数字
        long parseLong = Long.parseLong(input.nextLine());

        //计算将IP地址转换后的整数值并输出
        System.out.println(getIpToDecimal(split));
        //计算将十进制整数转换成IP地址并输出
        System.out.println(getDecimalToIp(parseLong));

    }

    /**
     * 将需要转换层IP地址的数字进行转换
     * @param inputNumber 需要转换成ip地址的十进制数
     * @return 返回转换好后的IP地址
     */
    private static String getDecimalToIp(long inputNumber){
        //将输入的十进制转换成32位的二进制
        ArrayList<Integer> decimalToBinary = getDecimalToBinary32(inputNumber);
        StringBuilder decimalToIp = new StringBuilder();//存储转换后的十进制IP地址
        ArrayList<Integer> arrayList = new ArrayList<>();//存储切分出来的八位二进制数列表

        for (int i = 0; i < decimalToBinary.size(); i++) {
            arrayList.add(decimalToBinary.get(i));
            if (arrayList.size()%8==0){//当当前列表有八位二进制就进行转换,转换成十进制
                decimalToIp.append(getBinaryToDecimal(arrayList));//将八位二进制转换成十进制数字
                if (i<decimalToBinary.size()-1){//防止出现IP地址后还有小数点
                    decimalToIp.append(".");
                }
                arrayList.clear();//清空当前八位二进制列表,方便下一次存储和计算
            }

        }
        return decimalToIp.toString();
    }

    /**
     * 将IP地址转换成整数数字
     * @param str 按"."切分后的IP地址数组
     * @return 转换成十进制后的整数
     */
    private static long getIpToDecimal(String[] str){
        ArrayList<Integer> binaryList = new ArrayList<>();//存储32位的二进制
        //将IP地址转换成32位二进制数
        for (String s : str) {
            //获取整数
            int strToDecimal = Integer.parseInt(s);
            //获取整数的8位二进制数并存放到32位二进制结果集中
            //Long.toBinaryString()
            ArrayList<Integer> decimalToBinary = getDecimalToBinary8(strToDecimal);
            binaryList.addAll(decimalToBinary);//将八位的二进制存储在一起组成32位的二进制
        }
        //将二进制数转换成十进制数
        return getBinaryToDecimal(binaryList);
    }

    /**
     * 将十进制的数组转换成二进制(8位)后
     *
     * @param number 传入需要转换的十进制
     * @return 返回转换好后的8位二进制数字
     */
    private static ArrayList<Integer> getDecimalToBinary8(int number) {
        ArrayList<Integer> flipBinary = new ArrayList<>();
        int tmp = number;
        for (int i = 1; i <= tmp; i++) {
            if (number % 2 == 0) {
                flipBinary.add(0);
                number /= 2;
            } else {
                flipBinary.add(1);
                number /= 2;
            }
            if (number == 1) {
                flipBinary.add(1);
                break;
            }
        }
        //如果计算出来的二进制没有8位,则在其后面补0
        while (flipBinary.size() < 8) {//while循环是先做后判断
            flipBinary.add(0);
        }

        //将上面计算好的二进制进行翻转存储,就像数学里面计算后从后面往上读取二进制数
        ArrayList<Integer> arrayList = new ArrayList<>();
        int n = flipBinary.size();
        for (int i = n-1; i >-1; i--) {
            arrayList.add(flipBinary.get(i));
        }

        return arrayList;
    }

    /**
     * 将十进制的数组转换成二进制(32位)后
     *
     * @param number 传入需要转换的十进制
     * @return 返回转换好后的32位二进制数字
     */
    private static ArrayList<Integer> getDecimalToBinary32(long number) {
        ArrayList<Integer> flipBinary = new ArrayList<>();
        long tmp = number;
        for (int i = 1; i <= tmp; i++) {
            if (number % 2 == 0) {
                flipBinary.add(0);
                number /= 2;
            } else {
                flipBinary.add(1);
                number /= 2;
            }
            if (number == 1) {
                flipBinary.add(1);
                break;
            }
        }
        //如果计算出来的二进制没有32位,则在其后面补0
        while (flipBinary.size() < 32) {//while循环是先做后判断
            flipBinary.add(0);
        }

        ArrayList<Integer> arrayList = new ArrayList<>();
        int n = flipBinary.size();
        for (int i = n-1; i >-1; i--) {
            arrayList.add(flipBinary.get(i));
        }
        return arrayList;
    }

    /**
     * 将二进制转换成十进制
     *
     * @param binary 需要转换的二进制列表
     * @return 返回转换好后的十进制数
     */
    private static long getBinaryToDecimal(ArrayList<Integer> binary) {
        int n = binary.size();
        long decimalNumber = 0;
        for (int i = 0; i < n; i++) {
            decimalNumber += Math.pow(2, n - i - 1) * binary.get(i);//pow:求2的n-i-1次方的值,100,1*pow(2,3-0-1)+1*pow(2,3-1-1)+1*pow(2,3-2-1)
        }

        return decimalNumber;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小雏菊的成长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值