对字符串依次扫描,仅允许出现数字和符号点,一旦遇到其他字符,即刻判断非法。

对于数字,逐个累加计算数值,如果某次数值超过 255,即刻判断非法。

如果遇到符号 . 或者 到达字符串末尾, 将已累计的 数值 保存到 ip_address 变量中, 同时 part 计数加 1。

最后需要严格 要求 part == 4。

#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <cctype>
using namespace std;

bool is_ok(const string& s, uint32_t& addr) {
    //允许有前导0的版本,例如 00000123.000000000.0001.231 视为合法ip
    int n = s.size();
    int val = 0, part = 0;
    addr = 0;
    for (int i = 0; i <= n; i++) {
        if (i == n or s[i] == '.') {
            addr = (addr << 8) | val;
            part++;
            val = 0;
        } else if ('0' <= s[i] and s[i] <= '9') {
            val = val * 10 + s[i] - '0';
            if (val > 255) {
                return false;
            }
        } else {
            return false; // 含有非法字符
        }
    }
    return part == 4;
}

int solve(string& mask, string& ip1, string& ip2){
    uint32_t addr_mask, addr_ip1, addr_ip2;
    bool ok1 = is_ok(mask, addr_mask);
    bool ok2 = is_ok(ip1, addr_ip1);
    bool ok3 = is_ok(ip2, addr_ip2);
    if(not ok1 or not ok2 or not ok3){
        return 1;
    }
    //检查掩码是否全是前导 1
    if(addr_mask + (addr_mask  & -addr_mask) != 0){
        return 1;
    }
    if((addr_ip1 & addr_mask) == (addr_ip2 & addr_mask)){
        return 0;
    }
    return 2;
}


int main() {
    string mask, ip1, ip2;
    cin >> mask >> ip1 >> ip2;
    cout << solve(mask, ip1, ip2);
}
// 64 位输出请用 printf("%lld")