思路:直接通过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()