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

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

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

import sys

def check_ip(ip_str):
    # 检查ip地址是否合法
    ip_data = ip_str.split(".")

    #是否是四位
    if len(ip_data) !=4:
        return False, []
    
    nums = []
    for part in ip_data:
        # 是否存在空段 10.0..1
        if not part:
            return False, []
        # 是否是数字
        if not part.isdigit():
            return False, []
        
        num = int(part)
        # 是否超过范围
        if num < 0 or num > 255:
            return False, []
        nums.append(num)
    return True, nums

def check_mask(mask__str):
    # 是否合法子网掩码
    valid, nums = check_ip(mask__str)
    if not valid:
        return False
    
    # 转换成二进制
    bin_str = ''
    for num in nums:
        # 十进制转成二进制,并填充到8位
        bin_str = bin_str + bin(num)[2:].zfill(8)
    
    # 检查是否全部为1或全部为0
    if bin_str.count("1") == 32 or bin_str.count("0")==32:
        return False

    # 检查是否连续1后接连续0
    found_zero = False
    for i in range(32):
        if bin_str[i] == '0':
            found_zero = True
        elif found_zero and bin_str[i] == '1':
            return False

    return True

def classify_ip(ip_nums):
    first_num = ip_nums[0]
    second_num = ip_nums[1]

    mark = None

    if 1 <= first_num <= 127:
        mark = "A"
    elif 128 <= first_num <= 191:
        mark = "B"
    elif 192 <= first_num <= 223:
        mark = "C"
    elif 224 <= first_num <= 239:
        mark = "D"
    elif 240 <= first_num <= 255:
        mark = "E"
    
    # 是否私有IP
    is_private = False
    if first_num == 10:
        is_private = True
    elif first_num == 172 and 16 <= second_num <= 31:
        is_private = True
    elif first_num == 192 and second_num == 168:
        is_private = True

    return mark, is_private



def run():
    # 一次性读取所有的输入,按照行切割
    data = sys.stdin.read().split("\n")
    # 剔除最后一个空行
    new_data = data[0:-1]
    # 定义一个存储器
    result = {"A":0, "B":0, "C":0, "D":0, "E":0, "error":0, "prv":0}
    # 逐行处理
    for line in new_data:
        # 判断输入是否合法
        if line.count("~") != 1:
            result["error"] = result["error"] + 1
            continue
        
        # 分割IP和mask
        ip_str, mask__str = line.split("~")

        # 检查是否为特殊IP(0.*.*.*或127.*.*.*)
        if ip_str.startswith('0.') or ip_str.startswith('127.'):
            # 进一步验证格式
            valid, ip_nums = check_ip(ip_str)
            if valid and (ip_nums[0] == 0 or ip_nums[0] == 127):
                # 特殊IP,直接跳过,不计入任何统计
                continue

        # 验证IP地址有效
        ip_valid, ip_nums = check_ip(ip_str)
        if not ip_valid:
            result['error'] += 1
            continue

        # 验证mask掩码的有效性
        mask_valid = check_mask(mask__str)
        if not mask_valid:
            result['error'] += 1
            continue

        # 分类统计
        mark, is_private = classify_ip(ip_nums)
        if mark:
            result[mark] += 1
        
        if is_private:
            result["prv"] += 1
    
    print(result["A"], result["B"], result["C"], result["D"], result["E"], result["error"], result["prv"])

run()

核心步骤

  1. 读取输入:使用 sys.stdin一直读取到文件结尾
  2. 解析每一行:分割 IP 地址和子网掩码
  3. 检查特殊 IP:跳过 0...* 和 127...*
  4. 验证格式和范围:检查 IP 和掩码格式是否合法
  5. 验证子网掩码:转换为二进制,检查是否符合连续1+连续0的规则
  6. 分类统计: 如果不合法,错误计数加1 如果合法,判断类别和是否为私有IP

关键细节

  1. IP地址格式验证: 必须是四段数字 每段必须是0-255的整数 不能有空段(如"10..1.1")
  2. 子网掩码验证: 先转换为32位二进制字符串 必须满足连续1后接连续0 不能全1或全0
  3. 特殊处理: 0...* 和 127...* 不参与任何统计(包括错误统计)
全部评论
对于连续1必须接连续0除了上述代码的方法,还可以直接通过检测是否存在“01”
点赞 回复 分享
发布于 02-05 09:56 陕西

相关推荐

在笔试的大西瓜很矫健:校招数分不用想了,这经历和学历都不够用,大厂更别想,初筛都过不了,说点不好听的小厂数分都进不去(小厂也是假数分),要两个对口实习+3个项目(或者3+2),而且要有含金量才能补一点你的学历劣势。 建议刷实习,社招找数分,校招看运气,能入行业就行,可以运营转数分
点赞 评论 收藏
分享
02-02 19:07
已编辑
河南师范大学 算法工程师
用微笑面对困难:一般5年老工都不太敢写“精通python”至少要达到noi的级别 兄弟你要是真精通大厂秒进的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务