解题思路:

  • 对字符串进行转换,就像HJ33那样将IP字符串转换为i32(用以校验数值范围),再转换为u32,这样就可保持编码不变并可进行下一步检验.
  • 掩码的连续1性质检验办法:rust基本数据类型中的几种(主要是指有符号数与无符号数)有一个count_ones()函数可以计算该数字二进制编码中所含1的数量,倘若无符号整数mask是正确掩码,其所含1应该都在前面且不间断,故而对其做位运算mask << mask.count_ones()必然为0,否则该数不符合掩码规则,不是正确掩码。

alt

代码分析:
害行,我看得下去,不知道你看不看得下去。

use std::io;

pub fn decstr_to_bin(s: &String) -> u32 {
    //ip地址字符串转u32,顺便做基本ip合法性检验
    if s.contains(".") {
        let numbers: Vec<&str> = s.split(".").collect();
        let a = numbers[0].trim().parse::<i32>().unwrap_or(0);
        let b = numbers[1].trim().parse::<i32>().unwrap_or(0);
        let c = numbers[2].trim().parse::<i32>().unwrap_or(0);
        let d = numbers[3].trim().parse::<i32>().unwrap_or(0);
        if (a < 256 && a >= 0) && (b < 256 && b >= 0) && (c < 256 && c >= 0) && (d < 256 && d >= 0)
        {
            String::from(format!("{}", ((a as u32) << 24) + ((b as u32) << 16) + ((c as u32) << 8) + (d as u32)))
                .parse::<u32>()
                .unwrap_or(u32::MAX)
        } else {
            u32::MAX
        }
    } else {
        u32::MAX
    }
}
fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).expect("Failed to read line");
    let mask = decstr_to_bin(&s);
    s.clear();
    io::stdin().read_line(&mut s).expect("Failed to read line");
    let ip_1 = decstr_to_bin(&s);
    s.clear();
    io::stdin().read_line(&mut s).expect("Failed to read line");
    let ip_2 = decstr_to_bin(&s);
    if mask == u32::MAX || ip_1 == u32::MAX || ip_2 == u32::MAX {
        println!("1");
    } else {
        if (mask << mask.count_ones()) == 0 {//掩码连续1检验
            if (mask & ip_1) == (mask & ip_2) {
                println!("0");
            } else {
                println!("2");
            }
        } else {
            println!("1");
        }
    }
}