题解 | #识别有效的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”不能被记为格式错误。