问题 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运算带来困难. 所以还是用字符串来存储
#include <iostream>
#include<cstring>
#include<cmath>
using namespace std;
void binary(int num,int start,int *bin);
//将数转化为二进制
int *translateIP(string s);
//把string转化为二进制数
int dicimal(int num);
//将二进制转换为十进制
string AND(int *IP,int *subnum);
//与子网掩码AND运算之后转化为10进制并加成一个数
void binary(int num,int start,int *bin) //将数转化为二进制,除二倒取余(倒着放)
{
int locate = start * 8;
for (int i=0;i<8;i++)
{
bin[7 - i + locate] = num % 2;
num /= 2;
}
}
int *translateIP(string s) //把string转化为二进制数
{
int num=0,order=0;
bool ifnewnum=0; //是否开始了新的数
int bin[32]={0}; //用来存二进制
for(int i=0;s[i]!='\0';i++)
{
if(s[i]=='.')
{
ifnewnum=1;
continue;
}
if(ifnewnum)
{
binary(num, order++,bin); //一个数取完就转换成二进制存入
num=0;
}
num=num*10+s[i]-'0';
ifnewnum=0;
}
binary(num,order,bin);
return bin;
}
int dicimal(int num) //将二进制转换为十进制
{
int temp,dicimalnumber=0;
for (int i=0;num != 0;i++)
{
temp = num % 10;
dicimalnumber+=temp*pow(2,i);
num /= 10;
}
return dicimalnumber;
}
string AND(int *IP,int *subnum) //与子网掩码AND运算
{
int num;
string s;
for(int i=0;i<32;i++)
{
num=IP[i]&subnum[i];
s+= char('0' + num);
}
return s; //虽然题目要求转化为十进制再比较,但可以直接用二进制形式判断
}
int main()
{
string IP,subnet_mask; //存原始IP和掩码
cin>>IP>>subnet_mask;
int IPnum[32];
memcpy(IPnum, translateIP(IP), sizeof(IPnum)); //将string转换成二进制数存入IPnum
int subnum[32];
memcpy(subnum, translateIP(subnet_mask), sizeof(subnum));//将string转换成二进制数存入subnum
string andIP= AND(IPnum,subnum),andother; //AND运算之后,用一个字符串存起来
int N; //接下来有N个IP
cin>>N;
string other; //存别的IP
for(int i=0;i<N;i++)
{
cin>>other;
int othernum[32];
memcpy(othernum, translateIP(other), sizeof(othernum));
andother=AND(othernum,subnum); //求出每个IP在与子网掩码and之后的值
if(andother==andIP)
cout<<"INNER"<<endl;
else if(andother!=andIP)
cout<<"OUTER"<<endl;
}
return 0;
}
网友评论