问题 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 }
来源:oschina
链接:https://my.oschina.net/u/4312544/blog/3503311