题解 | #识别有效的IP地址和掩码并进行分类统计#

识别有效的IP地址和掩码并进行分类统计

https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682

const rl = require("readline").createInterface({
    input: process.stdin,
    output: process.stdout,
});

const inputs = [];

rl.on("line", (line) => {
    inputs.push(line);
}).on("close", () => {
    const res = countIP(inputs);
    // 输出
    const { A, B, C, D, E, Err, Pri } = res;
    console.log(`${A} ${B} ${C} ${D} ${E} ${Err} ${Pri}`);
});

function countIP(inputs) {
    let countMap = {
        A: 0,
        B: 0,
        C: 0,
        D: 0,
        E: 0,
        Err: 0,
        Pri: 0,
    };

    for (let i = 0; i < inputs.length; i++) {
        const temp = inputs[i].split("~");

        let ip = temp[0],
            code = temp[1];

        const ipFirst = parseInt(ip.split(".")[0]);

        // 0.*.*.* | 127.*.*.* 直接忽略
        if (ipFirst === 0 || ipFirst === 127) {
            continue;
        } else {
            // 判断掩码 code 是否合法
            const binaryCode = codeTranstoBinary(code);
            const zeroIndex = binaryCode.indexOf(0);
            const oneIndex = binaryCode.lastIndexOf(1);

            if (zeroIndex > -1 && oneIndex > -1 && zeroIndex > oneIndex) {
                // 掩码合法之后判断ip是属于哪一类,还要注意是否属于私有
                countMap = typeOfIP(ip, countMap);
                // 私网
                validatePrivateIp(ip) && countMap["Pri"]++;
            } else {
                countMap.Err++;
            }
        }
    }

    return countMap;
}

// 255.255.255.255 => 11111111.11111111.11111111.11111111
function codeTranstoBinary(code) {
    let res = [];
    const codeArr = code.split(".");
    for (let i = 0; i < codeArr.length; i++) {
        const binary = parseInt(codeArr[i], 10).toString(2);
        res[i] = "00000000".slice(0, 8 - binary.length) + binary;
    }
    return res.join(".");
}

function typeOfIP(ip, map) {
    let res = map;

    if (validateIp(ip)) {
        const ipFirst = parseInt(ip.split(".")[0]);

        // A
        if (ipFirst >= 1 && ipFirst <= 126) {
            res["A"]++;
        }
        // B
        else if (ipFirst >= 128 && ipFirst <= 191) {
            res["B"]++;
        }
        // C
        else if (ipFirst >= 192 && ipFirst <= 223) {
            res["C"]++;
        }
        // D
        else if (ipFirst >= 224 && ipFirst <= 239) {
            res["D"]++;
        }
        // E
        else if (ipFirst >= 240 && ipFirst <= 255) {
            res["E"]++;
        }
    } else {
        res.Err++;
    }
    return res;
}

function validateIp(ip) {
    const re =
        /(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}/;
    return re.test(ip);
}

function validatePrivateIp(ip) {
    let validate = false;
    const ipFirst = ip.split(".")[0];

    if (ipFirst === "10") {
        validate = /10(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}/.test(ip);
    }
    if (ipFirst === "172") {
        validate =
            /172\.(1[6-9]|2\d|3[0-1])(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){2}/.test(
                ip
            );
    }

    if (ipFirst === "192") {
        validate = /192\.168(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){2}/.test(ip);
    }

    return validate;
}

难度:⭐⭐⭐⭐

题目:

输入一组类似 ”ip~掩码“,要找出有效的掩码和ip,并且给分类,最后输出每种分类的个数。

有 A、B、C、D、E、错误的掩码和ip、私网ip这7种分类,给出这组输入每种分类的个数。

关键点:

  • 0.*.*.*|127.*.*.* 这两种ip直接忽略不计数
  • 判断掩码是否有效
  • 判断ip是否有效
  • 判断ip是否是私网ip

难点:

  • 怎么判断掩码是否有效?
  • 子网掩码为二进制下前面是连续的1,然后全是0。 这是判断子网掩码的关键,起初我就没有理解错题目。
  • 根据上一点,所以掩码不能全是0,不能全是1,同时第一个0的下标比最后一个1的下标大,那这个掩码就是合法的。
  • 怎么判断ip是否有效?
  • 我用的是正则表达式,这题不用正则也行,我就单纯想用正则解题。
  • ip:0.255.255.255,有四段,每段最多三位数,分情况讨论每种情况写出对应的正则,最后合在一起。
  • [1-9]?\d|1\d{2}|2[0-4]\d|25[0-5] 这是一段的五种情况,0 | 10 | 192 | 245 | 255 对应的五种情况,\. 匹配小数点,合成四段。XXX.XXX.XXX.XXX
  • 判断私网ip有效,就是取ip的第一段,然后用对应的正则判断是否是有效的私网ip即可。

步骤:

理解了上面的难点,这道题就简单了,就是按:

1、遇到ip第一段是0 和 127就直接略过

2、判断掩码是否有效,无效就Err+1,有效就判断ip是否有效

3、ip有效就判断是哪一类的ip,对应的类型计数+1

4、ip有效再判断是不是属于私网ip,是私网就Pri+1

5、如果ip无效就Err+1

这道题属于不会之前难,会后不难,…… 难点还是上面提到的那两个难点,过程中的细节小心一点即可。

掌握正则的分析与拼凑

全部评论

相关推荐

11-15 17:19
湖南大学 Java
成果成果成果果:这是哪个公司的hr,这么离谱吗,我没见过用性别卡技术岗的,身边女性同学拿大厂offer的比比皆是
点赞 评论 收藏
分享
像好涩一样好学:这公司我也拿过 基本明确周六加班 工资还凑活 另外下次镜头往上点儿
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务