思路:直接通过A到E类地址的格式来匹配,然后再局部判断是否为合法ip
易错点:1.ip地址或者掩码其中一个出错,输入行就算错误行了,所以需要提前先判断掩码,如果先判断ip,容易提前累加ip的数,实际错的掩码下即使ip正确也不能算正确
2.掩码的判断过程中,需要讲int转化为8位二进制串,一定要保留第一个1之前的0值,否则会误判
import sys
def is_legal_addr(sections):
for sec in sections[1:]:
if sec < 0&nbs***bsp;sec > 255:
return 0
return 1
def is_error_mark(mark):
secs = list(map(int, mark.split(".")))
if secs[0] == secs[1] == secs[2] == secs[3] and (0 == secs[0]&nbs***bsp;255 == secs[0]):
return True
# "{0:b}".format(sec)这样写是不保留高位,只从第一个1保留:16 -> "10000"
# "{0:8b}".format(sec)这样写是保留8位二进制,第一个1之前的0被空格替代:16 -> " 10000"
# "{0:08b}".format(sec)这样写是保留8位二进制,第一个1之前的0原封不动填充:16 -> "00010000"
sections = ["{0:08b}".format(sec) for sec in secs]
cnt = 0
first_zero = 33
last_one = 0
for sec in sections:
for i in sec:
cnt += 1
if '0' == i and 33 == first_zero:
first_zero = cnt
elif '1' == i:
last_one = cnt
if last_one >= first_zero:
return True
return False
def main():
a_cnt = b_cnt = c_cnt = d_cnt = e_cnt = 0
private_cnt = err_cnt = 0
for line in sys.stdin:
vec = str(line.strip()).split("~")
addr = vec[0]
mark = vec[1]
sections = []
err_flag = is_error_mark(mark)
for i in addr.split("."):
if not i:
sections.append(-1)
else:
sections.append(int(i))
if sections[0] >= 1 and sections[0] <= 126:
ret = is_legal_addr(sections)
if 1 == ret and not err_flag:
a_cnt += 1
if 10 == sections[0]:
private_cnt += 1
else:
err_flag = True
elif sections[0] >= 128 and sections[0] <= 191:
ret = is_legal_addr(sections)
if 1 == ret and not err_flag:
b_cnt += 1
if 172 == sections[0] and sections[1] >= 16 and sections[1] <= 31:
private_cnt += 1
else:
err_flag = True
elif sections[0] >= 192 and sections[0] <= 223:
ret = is_legal_addr(sections)
#print(sections, ret, err_flag)
if 1 == ret and not err_flag:
c_cnt += 1
if 192 == sections[0] and 168 == sections[1]:
private_cnt += 1
else:
err_flag = True
elif sections[0] >= 224 and sections[0] <= 239:
ret = is_legal_addr(sections)
if 1 == ret and not err_flag:
d_cnt += 1
else:
err_flag = True
elif sections[0] >= 240 and sections[0] <= 255:
ret = is_legal_addr(sections)
if 1 == ret and not err_flag:
e_cnt += 1
else:
err_flag = True
if err_flag:
err_cnt += 1
print(a_cnt, b_cnt, c_cnt, d_cnt, e_cnt, err_cnt, private_cnt)
main() 


京公网安备 11010502036488号