题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
bool judge_ip(string ip) {
int cnt = 0; // 以'.'分割IP,记录有几段
istringstream iss(ip);
string seg;
while(getline(iss, seg, '.')) {
if(++cnt > 4 || seg.empty() || stoi(seg) > 255)
return false; // 非法IP
}
return cnt == 4; // 少于4段也是非法IP
}
bool is_private(string ip) {
istringstream iss(ip);
string seg;
vector<int> v;
while(getline(iss, seg, '.')) v.push_back(stoi(seg));
if(v[0] == 10) return true;
if(v[0] == 172 && (v[1]>=16 && v[1]<=32)) return true;
if(v[0] == 192 && v[1] == 168) return true;
return false;
}
bool is_mask(string ip) {
istringstream iss(ip);
unsigned int b = 0;
string seg;
while(getline(iss, seg, '.'))
b = (b<<8) + stoi(seg);
if(!b) return false; // 全0
b = ~b;
if(b == 0) return false; // 全1
if(((b+1) & b) == 0) return true; // 是否为连续的'1'
return false;
}
int main() {
int a = 0, b = 0, c = 0, d = 0, e = 0, err = 0, p = 0;
string input;
while(cin >> input) {
istringstream is(input);
string str;
vector<string> vec;
while(getline(is, str, '~')) vec.push_back(str); // 用'~'分割IP和Mask
if(judge_ip(vec[1]) && judge_ip(vec[0])) {
int first = stoi(vec[0].substr(0, vec[0].find_first_of('.')));
if(first == 0 || first == 127) continue; // 注意!!!!
if(is_mask(vec[1])) {
if(is_private(vec[0])) ++p; // 私网IP
// 判断几类地址
if(first > 0 && first < 127) ++a;
else if(first > 127 && first < 192) ++b;
else if(first > 191 && first < 224) ++c;
else if(first > 223 && first < 240) ++d;
else if(first > 239 && first < 256) ++e;
}
else {
++err;
}
}
else {
++err;
}
}
cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << ' ' << err << ' ' << p;
return 0;
}
// 64 位输出请用 printf("%lld")
注意规则:类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
该规则比正确的掩码优先级更高,即使掩码不对,但只要IP满足【0.*.*.*】或【127.*.*.*】格式,都应该忽略不计。
例如“127.201.56.50~255.255.111.255”不能被记为格式错误。
360集团公司氛围 372人发布