1.描述
见牛客网
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
2. 分析
根据题目要求,分为以下几步
1. 提取IP地址和子网掩码
我们首先需要拆分输入的每一行,分别提取IP地址和子网掩码,并检查它们的合法性。
2. 分类解析识别IP地址
根据题目提供的IP地址范围,将IP地址分类为A/B/C/D/E类地址。同时,检查IP地址是否属于私有IP地址。
3. 检查子网掩码的合法性
合法的子网掩码必须是二进制下前面是连续的1,然后全是0。非法的子网掩码需要单独归类。
4. 统计结果
最后,将所有的分类结果统计并输出。ip或者子网有一个为非法,就记为非法并统计下一条
3.代码
import sys
import re
def is_sw(ip):
nums = ip.split('.')
one = int(nums[0])
two = int(nums[1])
if one == 10:
return True
elif one == 172 and 16<=two<=32:
return True
elif one == 192 and two==168:
return True
return False
def is_ip(ip):
k = int(ip.split(".")[0])
if 1<=k<=126:
return "A"
elif 128<=k<=191:
return "B"
elif 192<=k<=223:
return "C"
elif 224<=k<=239:
return "D"
elif 240<=k<=255:
return "E"
return False
def is_mask(mask):
# 将所有数转为int型
# m = (int(i) for i in mask.split("."))
# # 将所有数转为二进制
# m = (bin(i) for i in m)
# # 连接成一个字符串,每一个去掉0b前缀,左补全0
# mask_str = "".join( i[2:].zfill(8) for i in m)
# 上面的也可以写成一句
mask_str = "".join([bin(int(i))[2:].zfill(8) for i in mask.split(".")])
# 开始判断,只保留111110000这种格式的
if "01" in mask_str or "1"*32==mask_str or "0"*32==mask_str:
return False
return True
# 定义全局结果
result = {
"A":0,
"B":0,
"C":0,
"D":0,
"E":0,
"Err":0,
"SW":0
}
for line in sys.stdin:
# 提取 Ip 和 mask
ip,mask = line.split("~")
# 提取无效 Ip 或者 无效掩码,不计数,开始下一行
# 去掉非 1.12.123.123 这种格式的,如19..10.,注意这里没有过滤 大于 255的
# 注意这里 . 要转义,用\.
ip_ptn = "^(\d{1,3}\.){3}\d{1,3}$"
if not re.match(ip_ptn,ip) or not re.match(ip_ptn,mask):
result["Err"] += 1
continue
# 去掉 0 和127 开头的
if ip.startswith("0.") or ip.startswith('127.'):
continue
# 转为列表
ip_part = list(map(int,ip.split(".")))
mask_part = list(map(int,mask.split(".")))
# 识别大于255的,因为\d是0-9,所以小于0的会在上面过滤掉了
if any(i>255 for i in ip_part) or any(m>255 for m in mask_part):
result["Err"]+=1
continue
# 识别非法掩码
if not is_mask(mask):
result["Err"] += 1
continue
# 因为 ip类型和私网IP不冲突,所有不用continue,两都都判断
# 识别IP地址
ip_type = is_ip(ip)
if ip_type != False:
result[ip_type] += 1
# 识别私网IP地址
if is_sw(ip):
result["SW"] += 1
for v in result.values():
print(v,end=" ")
4.知识点
1.any()的用法
any(可迭代对象) 表示,可迭代对象中,有一项为真返回真
列中用来判断 所有都要小于255的情况,即
# 表示列表中所有数任何一个大于255就返回真,所有都小于255就返回假
any(i >255 for i in list)
这里还有一个all()函数,表示可迭代对象中,有全部为真才返回真,即有一项为假就返回假
# 表示所有的都要小于255才返回真,任何一个大于255就为假
all(i<255 for i in list)
2.正则式
# 如果能在 str 内匹配到 ptn 就返回真,否则为假
re.match(ptn,str)
3.常用方法
方法名 | 描述 |
---|---|
join(t) | 连接字符串t |
startswith(d) | 以d开头 |
split© | 按c拆分 |
bin(n) | 整数n转二进制 |
int(s) | 字符s转int |
zfill(n) | 左补n位全零 |
rjust(n,c) | 右补n对应c字符 |
ljust(n,c) | 左补n对应c字符 |