题解 | #判断两个IP是否属于同一子网#

判断两个IP是否属于同一子网

https://www.nowcoder.com/practice/34a597ee15eb4fa2b956f4c595f03218

重要的是掩码连续为1然后连续为0的判断,需要位运算,准则为:

  1. 将掩码地址转换为32位无符号整型,假设这个数为b。如果此时b为0,则为非法掩码
  2. 将b按位取反后+1。如果此时b为1,则b原来是二进制全1,非法掩码
  3. 如果b和b-1做按位与运算后为0,则说明是合法掩码,否则为非法掩码
#include <bits/stdc++.h>
using namespace std;

vector<int> vpm;
vector<int> vpi;
vector<int> vpi2;



bool check_mask(string x) {
    int i = 0;
    int j = 0;
    
    while (i < x.size() and j < x.size()) {
        while (i < x.size() and !isdigit(x[i])) {
            if (x[i] != '.') return false;
            j = ++i;
        }
        while (j < x.size() and isdigit(x[j])) j++;
        int tt = stoi(x.substr(i, j - i));
        if (tt < 0 or tt > 255) return false;
        vpm.push_back(tt);
        i = ++j;
    }
    if (vpm.size() != 4) return false;
    unsigned b = 0;
    for (int x : vpm) {
        b = (b << 8) + x;
    }
    if (b == 0) return false;
    if (~b + 1 == 1) return false;
    b = ~b + 1;
    if ((b & (b - 1)) == 0) return true;
    return false;
}

bool check_ip(string x) {
    int i = 0;
    int j = 0;
    while (i < x.size() and j < x.size()) {
        while (i < x.size() and !isdigit(x[i])) {
            if (x[i] != '.') return false;
            j = ++i;
        }
        while (j < x.size() and isdigit(x[j])) j++;
        int tt = stoi(x.substr(i, j - i));
        if (tt < 0 or tt > 255) return false;
        vpi.push_back(tt);
        i = ++j;
    }
    if (vpi.size() != 4) return false;
    return true;
}

bool check_ip2(string x) {
    int i = 0;
    int j = 0;
    while (i < x.size() and j < x.size()) {
        while (i < x.size() and !isdigit(x[i])) {
            if (x[i] != '.') return false;
            j = ++i;
        }
        while (j < x.size() and isdigit(x[j])) j++;
        int tt = stoi(x.substr(i, j - i));
        if (tt < 0 or tt > 255) return false;
        vpi2.push_back(tt);
        i = ++j;
    }
    if (vpi2.size() != 4) return false;
    return true;
}


int main() {
    string c, a, b;
    while (cin >> c >> a >> b) { // 注意 while 处理多个 case
    vpi.clear();
    vpm.clear();
    vpi2.clear();
    if (check_mask(c) and check_ip(a) and check_ip2(b)) {
        bool flag = true;
        for(int i = 0; i < 4; i++){
            if((vpm[i] & vpi[i]) != (vpm[i] &vpi2[i])){
                flag = false;
                break;
            }
        }
        if (flag) cout << "0" << endl;
        else cout << "2" << endl;
    }
    else cout << "1" << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

头像
11-09 12:17
清华大学 C++
out11Man:小丑罢了,不用理会
点赞 评论 收藏
分享
hso_:哈哈哈哈哈哈我没offer一样在同一道题开喷了
投递深圳同为数码等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务