题解 | #判断两个IP是否属于同一子网#
判断两个IP是否属于同一子网
http://www.nowcoder.com/practice/34a597ee15eb4fa2b956f4c595f03218
考察点
- 如何使用C++的
string
对输入字符串进行分解? - 认识到IP只有四个网段,然后如何对这四个子段进行处理?
- 如何判定输入的四个子段是否都是合法的?
注意:不合四个子段都应在
0 ~ 255
, 针对掩码还需要判断前后缀是否合理
设计一个IP类
class IP
{
public:
IP(){ for(int i = 0; i < 4; ++i) _ip[i] = -1;} // 初始化
IP(const int* ip);
void in(); // 处理标准输入的字符串
bool is_valid() const; // 判断是否都在0~255内合法
bool is_uninit() const; // delted
bool is_zero() const; // deleted
bool is_mask() const; // 判断是否为合法掩码
friend IP operator&(const IP& ip, const IP& mask); // and 操作
friend bool operator==(const IP& ip1, const IP& ip2); // 判断是否为同一个IP的操作,也可以用来判断是否在同一个网段
private:
int _ip[4];
};
实现
IP::IP(const int* ip)
{
memcpy(_ip, ip, sizeof(int)*4);
}
void IP::in()
{
std::string str;
std::cin >> str;
size_t pos = 0;
for(int i = 0; i < 3; ++i)
{
pos = str.find('.');
std::string one = str.substr(0, pos);
_ip[i] = atoi(one.c_str());
str.erase(0, pos+1);
}
_ip[3] = atoi(str.c_str());
}
bool IP::is_valid() const
{
for(int i = 0; i < 4; ++i)
{
if(_ip[i] < 0 || _ip[i] > 255)
return false;
}
return true;
}
bool IP::is_mask() const
{
// 如何判断掩码正确与否
for(int i = 0; i < 3; ++i)
{
if(_ip[i] < _ip[i+1])
return false;
}
return true;
}
bool operator==(const IP& ip1, const IP& ip2)
{
for(int i = 0; i < 4; ++i)
{
if(ip1._ip[i] != ip2._ip[i])
return false;
}
return true;
}
IP operator&(const IP& ip, const IP& mask)
{
int _ip[4];
for(int i = 0; i < 4; ++i)
_ip[i] = ip._ip[i] & mask._ip[i];
return IP(_ip);
}
逻辑
main函数
while(!std::cin.eof())
{
IP mask;
mask.in();
IP ip1;
ip1.in();
IP ip2;
ip2.in();
// 判断输入是否非法输入
if(!mask.is_mask() || !mask.is_valid() || !ip1.is_valid() || !ip2.is_valid())
std::cout << 1 << std::endl;
// 判断是否同一个子网络
else if((ip1&mask) == (ip2&mask))
std::cout << 0 << std::endl;
else
std::cout << 2 << std::endl;
}