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

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

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

题目的主要信息:

  • 利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。
  • 掩码与IP每一段在 0 - 255 之间。掩码的二进制字符串前缀为网络号,都由‘1’组成;后缀为主机号,都由'0'组成

方法一:

按照题目的思路求解。第一步是判断ip地址和掩码的格式是否合法,由题意可知,掩码与IP每一段在 0 - 255 之间,如果有字段小于0或者大于255则直接判为格式非法;若字段都在 0 - 255 之间,判断掩码是否前缀为1,后缀为0,根据归纳推理发现,若0<mask[i]<255,则第i段已经包含0了,那么从第i+1段开始必须全为0,因此若mask[i+1]>0,则格式非法。

格式都合法后,分别对两个ip地址逐段进行AND操作,若结果相同则输出0,否则输出2; alt

具体做法:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> mask(4,0);
    vector<int> ip1(4,0);
    vector<int> ip2(4,0);
    char c;
    while (cin>>mask[0]>>c>>mask[1]>>c>>mask[2]>>c>>mask[3])//输入掩码
    {
        int flag = -1;//结果
        cin>>ip1[0]>>c>>ip1[1]>>c>>ip1[2]>>c>>ip1[3];//第一个ip地址
        cin>>ip2[0]>>c>>ip2[1]>>c>>ip2[2]>>c>>ip2[3];//第二个ip地址
        for(int i=0;i<4;i++)//两个ip地址和掩码每一段都要在0-255之间
        {
            if(mask[i]<0 || mask[i]>255 || ip1[i]<0 || ip1[i]>255 ||ip2[i]<0 || ip2[i]>255)
            {
                flag = 1;//格式非法
                break;
            }
        }
        for(int i=0;i<3;i++)//掩码的网络号全为1,主机号全为0
        {
            if(mask[i]<255 && mask[i+1]>0)
            {
                flag = 1;
                break;
            }
        }
        if(flag==1)//格式非法,输出1
        {
            cout<<flag<<endl;
        }else{
            for(int i=0;i<4;i++)
            {
                if((mask[i]&ip1[i])!=(mask[i]&ip2[i]))//两个ip地址和掩码做AND操作
                {
                    flag = 2;
                    break;
                }else{//AND操作结果不相同
                    flag = 0;
                }
            }
            cout<<flag<<endl;
        }
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(1)O(1)O(1),判断格式合法和进行与操作都只需要常数时间。
  • 空间复杂度:O(1)O(1)O(1),只使用了常数空间。

方法二:

判断格式是否合法的时候可以用正则表达式来判断,((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d).){4}可以判断每个字段是否在0-255。首先把vector类型转换为string,再用regex_match函数和表达式进行匹配,若匹配返回true,否则返回false。进行格式非法判断的时候,用&&进行合并,只要有一个地址不合法,就返回1。

具体做法:

#include<iostream>
#include<vector>
#include<string>
#include<regex>

using namespace std;

int main()
{
    vector<int> mask(4,0);
    vector<int> ip1(4,0);
    vector<int> ip2(4,0);
    regex pattern("((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)\.){4}");//匹配0.0.0.0.-255.255.255.255.的正则表达式
    char c;
    while (cin>>mask[0]>>c>>mask[1]>>c>>mask[2]>>c>>mask[3])//输入掩码
    {
        int flag = -1;//结果
        cin>>ip1[0]>>c>>ip1[1]>>c>>ip1[2]>>c>>ip1[3];//第一个ip地址
        cin>>ip2[0]>>c>>ip2[1]>>c>>ip2[2]>>c>>ip2[3];//第二个ip地址
        string str_mask,str_ip1,str_ip2;
        for(int i=0;i<4;i++){
            str_mask+=to_string(mask[i])+'.';
            str_ip1+=to_string(ip1[i])+'.';
            str_ip2+=to_string(ip2[i])+'.';
        }
        if((regex_match(str_mask,pattern)&&regex_match(str_ip1,pattern)&&regex_match(str_ip2,pattern))==false)
        {
            flag=1;
        }
        for(int i=0;i<3;i++)//掩码的网络号全为1,主机号全为0
        {
            if(mask[i]<255 && mask[i+1]>0)
            {
                flag = 1;
                break;
            }
        }
        if(flag==1)//格式非法,输出1
        {
            cout<<flag<<endl;
        }else{
            for(int i=0;i<4;i++)
            {
                if((mask[i]&ip1[i])!=(mask[i]&ip2[i]))//两个ip地址和掩码做AND操作
                {
                    flag = 2;
                    break;
                }else{//AND操作结果相同
                    flag = 0;
                }
            }
            cout<<flag<<endl;
        }
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(1)O(1)O(1),判断格式合法和进行与操作都只需要常数时间。
  • 空间复杂度:O(1)O(1)O(1),只使用了常数空间。
全部评论
第一个方法,如果子网掩码是11111111.11111111.11101111.00000000这种在其中一段里0在1前面的情况是不是检测不出来啊
4 回复 分享
发布于 2022-02-12 15:09
测不出来
点赞 回复 分享
发布于 2022-08-09 23:30
对,这个掩码是否合理的检测是有问题的,只是这道题能过而已
点赞 回复 分享
发布于 2022-08-18 10:27 浙江
掩码检测有问题,只能通过部分样例.检测只考虑到网络号全为1,主机号全为0的正常状态;所以判断的前提都是以第一位不为0的情况代入,一旦掩码全为0,这个检测就错了
点赞 回复 分享
发布于 2022-11-01 11:24 贵州
这么数据输入的处理真的可以吗
点赞 回复 分享
发布于 2023-04-19 11:43 辽宁
掩码255.255.255.1,通过了
点赞 回复 分享
发布于 2023-07-01 20:46 广东

相关推荐

10-15 16:27
门头沟学院 C++
LeoMoon:建议问一下是不是你给他付钱😅😅
点赞 评论 收藏
分享
11-01 20:03
已编辑
门头沟学院 算法工程师
Amazarashi66:这种也是幸存者偏差了,拿不到这个价的才是大多数
点赞 评论 收藏
分享
评论
7
2
分享
牛客网
牛客企业服务