题解 | #判断两个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")

全部评论

相关推荐

来个厂收我吧:首先,市场侧求职我不是很懂。 但是,如果hr把这份简历给我,我会觉得求职人不适合做产品经理。 问题点: 1,简历的字体格式不统一,排版不尽如人意 2,重点不突出,建议参考star法则写个人经历 3,印尼官方货币名称为印度尼西亚卢比(IDR),且GMV690000印尼盾换算为305人民币,总成交额不高。 4,右上角的意向职位在发给其他公司时记得删除。 5,你所有的经历都是新媒体运营,但是你要投市场营销岗位,jd和简历不匹配,建议用AI+提示词,参照多个jd改一下经历内容。 修改建议: 1,统一字体(中文:思源黑体或微软雅黑,英文数字:time new romans),在word中通过表格进行排版(b站学) 2,校招个人经历权重:实习经历=创业经历(大创另算)>项目经历>实训经历>校园经历 3,请将项目经历时间顺序改为倒序,最新的放最上方。 4,求职方向不同,简历文字描述侧重点也需要不同。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务