子网掩码

问题 A: 子网掩码

时间限制: 1 Sec 内存限制: 32 MB
提交: 146 解决: 86
[提交][状态][讨论版]

题目描述

子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
最为简单的理解就是两台计算机各自的IP地址与子网掩码进行AND运算后,如果得出的结果是相同的,则说明这两台计算机是处于同一个子网络上的,可以进行直接的通讯。就这么简单。

请看以下示例:

运算演示之一:
IP地址  192.168.0.1
子网掩码  255.255.255.0

转化为二进制进行运算:
IP地址  11010000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000

AND运算:
     11010000.10101000.00000000.00000000

转化为十进制后为:
      192.168.0.0

运算演示之二:
IP地址  192.168.0.254
子网掩码  255.255.255.0

转化为二进制进行运算:
IP地址  11010000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000

AND运算:
     11010000.10101000.00000000.00000000

转化为十进制后为:
      192.168.0.0

运算演示之三:
IP地址  192.168.0.4
子网掩码  255.255.255.0

转化为二进制进行运算:
IP地址  11010000.10101000.00000000.00000100
子网掩码 11111111.11111111.11111111.00000000

AND运算:
     11010000.10101000.00000000.00000000

转化为十进制后为:
      192.168.0.0

通过以上对三组计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的,均为192.168.0.0,所以计算机就会把这三台计算机视为在同一子网络。

输入

输入的第一行是本机IP地址;
第二行是子网掩码;
第三行是一个整数N,表示后面有N个IP地址;
接下来N行:
第1个IP地址
...
...
第N个IP地址

输出

计算并输出N个IP地址是否与本机在同一子网内。对于在同一子网的输出“INNER”,对于在不同子网的输出“OUTER”。

样例输入

192.168.0.1
255.255.255.0
3
192.168.0.2
192.168.0.254
192.168.1.2

样例输出

INNER
INNER
OUTER

 就用了数组, string, 这些简单的存储结构写的. 在转化成二进制那里, 本来想用一个数来存储, 但是如果前面有0, 就会给后面的and运算带来困难. 所以还是用字符串来存储

  1 #include <iostream>
  2 #include<cstring>
  3 #include<cmath>
  4 using namespace std;
  5 
  6 void binary(int num,int start,int *bin);        
  7 //将数转化为二进制
  8 int *translateIP(string s);
  9 //把string转化为二进制数        
 10 int dicimal(int num);
 11 //将二进制转换为十进制
 12 string AND(int *IP,int *subnum);
 13 //与子网掩码AND运算之后转化为10进制并加成一个数
 14 
 15 void binary(int num,int start,int *bin)     //将数转化为二进制,除二倒取余(倒着放)
 16 {
 17     int locate = start * 8;
 18     for (int i=0;i<8;i++)
 19     {
 20         bin[7 - i + locate] = num % 2;
 21         num /= 2;
 22     }
 23 }
 24 
 25 int *translateIP(string s)      //把string转化为二进制数
 26 {
 27     int num=0,order=0;
 28     bool ifnewnum=0;        //是否开始了新的数
 29     int bin[32]={0};        //用来存二进制
 30     for(int i=0;s[i]!='\0';i++)
 31     {
 32         if(s[i]=='.')
 33             {
 34                 ifnewnum=1;
 35                 continue;
 36             }
 37         if(ifnewnum)
 38             {
 39                 binary(num, order++,bin);       //一个数取完就转换成二进制存入
 40                 num=0;
 41             }
 42         num=num*10+s[i]-'0';
 43         ifnewnum=0;
 44     }
 45     binary(num,order,bin);
 46     return bin;
 47 }
 48 
 49 
 50 int dicimal(int num)        //将二进制转换为十进制
 51 {
 52     int temp,dicimalnumber=0;
 53      for (int i=0;num != 0;i++)
 54     {
 55         temp = num % 10;
 56         dicimalnumber+=temp*pow(2,i);
 57         num /= 10;
 58     }
 59     return dicimalnumber;
 60 }
 61 
 62 string AND(int *IP,int *subnum)     //与子网掩码AND运算
 63 {
 64     int num;
 65     string s;
 66     for(int i=0;i<32;i++)
 67     {
 68         num=IP[i]&subnum[i];
 69         s+= char('0' + num);
 70     }
 71     return s;       //虽然题目要求转化为十进制再比较,但可以直接用二进制形式判断
 72 }
 73 
 74 int main()
 75 {
 76     string IP,subnet_mask;      //存原始IP和掩码
 77     cin>>IP>>subnet_mask;
 78 
 79     int IPnum[32];
 80     memcpy(IPnum, translateIP(IP), sizeof(IPnum));  //将string转换成二进制数存入IPnum
 81     int subnum[32];
 82     memcpy(subnum, translateIP(subnet_mask), sizeof(subnum));//将string转换成二进制数存入subnum
 83     string andIP= AND(IPnum,subnum),andother;       //AND运算之后,用一个字符串存起来
 84 
 85     int N;      //接下来有N个IP
 86     cin>>N;
 87     string other;       //存别的IP
 88     for(int i=0;i<N;i++)
 89     {
 90         cin>>other;
 91         int othernum[32];
 92         memcpy(othernum, translateIP(other), sizeof(othernum));
 93 
 94         andother=AND(othernum,subnum);      //求出每个IP在与子网掩码and之后的值
 95         if(andother==andIP)
 96             cout<<"INNER"<<endl;
 97         else if(andother!=andIP)
 98             cout<<"OUTER"<<endl;
 99     }
100     return 0;
101 }

 

posted @ 2019-06-12 20:25  步行植物  阅读(675)  评论(0编辑  收藏  举报