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

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

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

import sys
import re

def is_valid_ip(parts):			#统计错误IP
    if len(parts) != 4:			#当IP不是四位时返回False
        return False
    for p in parts:				#当IP每一段中有不为纯数字或者范围异常时,返回False
        if not p.isdigit() or not 0 <= int(p) <= 255:
            return False
    return True

def is_valid_mask(mask_parts):	#统计错误子网掩码
    if not is_valid_ip(mask_parts):		#如果不符合IP判断,返回False
        return False
    bin_mask = ''.join(f"{int(p):08b}" for p in mask_parts)	#将子网掩码转换为8位二进制字符串并拼接
    if '01' in bin_mask:	#如果有01则返回False
        return False
    if bin_mask.count('1') == 0 or bin_mask.count('0') == 0:	#如果全是0或者全是1则返回False
        return False
    return True

counts = [0] * 7	#统计列表

for line in sys.stdin:	#标准输入,一次一行的处理
    line = line.strip()	#去除这一行行首位的空白字符,包括换行符,空格
    if not line:		#跳过输入空的字符串
        continue
    try:	#尝试运行代码
        ip_str, mask_str = line.split('~')	#分割IP和子网掩码
        ip_parts = ip_str.split('.')		#将IP中四个数字分割
        mask_parts = mask_str.split('.')	#将掩码中四个数字分割

        if ip_parts[0] in ['0', '127']:	#0和127开头的IP直接跳过
            continue

        if not is_valid_ip(ip_parts) or not is_valid_mask(mask_parts):	#如果判断返回False则加一
            counts[5] += 1
            continue

        first = int(ip_parts[0])	#IP的第一位
        second = int(ip_parts[1])	#IP的第二位

        if 1 <= first <= 126:	#A类IP
            counts[0] += 1
        elif 128 <= first <= 191:	#B类IP
            counts[1] += 1
        elif 192 <= first <= 223:	#C类IP
            counts[2] += 1
        elif 224 <= first <= 239:	#D类IP
            counts[3] += 1
        elif 240 <= first <= 255:	#E类IP
            counts[4] += 1

        if first == 10:			#私有IP范围"10.0.0.0"∼"10.255.255.255"
            counts[6] += 1
        elif first == 172 and 16 <= second <= 31:	#私有IP范围"172.16.0.0"∼"172.31.255.255"
            counts[6] += 1
        elif first == 192 and second == 168:	#私有IP范围"192.168.0.0"∼"192.168.255.255"
            counts[6] += 1

    except:
        counts[5] += 1  # 尝试运行失败则错误IP+1

print(' '.join(map(str, counts)))	#输出内容

思路见解析!这题很棒啊一定要弄懂!!!

注意:

1.第15行是对于子网掩码中的元素首先使用int将转化为数字,然后使用08b转化为8位二进制数(不足用0填充),再使用join将它们拼接起来!!!f" "是格式化字符串,可以在字符串中直接嵌入变量或表达式;f"{int(p):08b}" for p in mask\_parts返回是一个懒字符串,如果是(f"{int(p):08b}" for p in mask\_parts)返回元组,[f"{int(p):08b}" for p in mask\_parts] 返回列表

2.第24行 sys.stdin 是使用标准输入读取内容,for line in sys.stdin: 是对sys.stdin 中每一行单独处理运行下面程序

3.try函数是尝试运行代码,可能会出错,使用try运行代码可以防止程序因为一点小异常而崩掉,try结束后会接上except,使用except SomeException:可以执行如果发生(SomeException)的错误时,运行的代码;如果没有加入SomeException程序就会在try中出现异常后直接执行except中的代码,本程序中可能出错的地方在29,30,31行中分割部分(可能输入中没有分割符号)

全部评论

相关推荐

06-07 00:00
已编辑
腾讯_后端开发
点赞 评论 收藏
分享
05-29 09:02
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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