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

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

http://www.nowcoder.com/questionTerminal/de538edd6f7e4bc3a5689723a7435682

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


全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务