题解 | 识别有效的IP地址和掩码并进行分类统计
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
#include <iostream> #include <sstream> #include <string> #include <vector> #include <cctype> using namespace std; // 判断字符串是否为纯数字,且无前导零(允许0) bool is_valid_segment(const string& s) { if (s.empty()) return false; if (s.size() > 1 && s[0] == '0') return false; for (char ch : s) if (!isdigit(ch)) return false; return true; } // 将字符串按 '.' 分割 vector<string> split(const string& s, char delim) { vector<string> res; stringstream ss(s); string item; while (getline(ss, item, delim)) res.push_back(item); return res; } // 检查IP是否合法 bool is_valid_ip(const vector<string>& ip) { if (ip.size() != 4) return false; for (const string& seg : ip) { if (!is_valid_segment(seg)) return false; int num = stoi(seg); if (num < 0 || num > 255) return false; } return true; } // 检查掩码是否合法 bool is_valid_mask(const vector<string>& mask) { if (mask.size() != 4) return false; string bin; for (const string& seg : mask) { if (!is_valid_segment(seg)) return false; int num = stoi(seg); if (num < 0 || num > 255) return false; for (int i = 7; i >= 0; --i) bin += ((num >> i) & 1) ? '1' : '0'; } // 合法掩码是若干1后若干0,中间不能出现01->0->1 size_t first_zero = bin.find('0'); if (first_zero == string::npos) return false; // 全1非法 size_t first_one_after_zero = bin.find('1', first_zero); if (first_one_after_zero != string::npos) return false; // 全0非法 if (bin.find('1') == string::npos) return false; return true; } // 判断IP类型 int get_ip_type(const vector<string>& ip) { int first = stoi(ip[0]); if (first >= 1 && first <= 126) return 0; // A if (first >= 128 && first <= 191) return 1; // B if (first >= 192 && first <= 223) return 2; // C if (first >= 224 && first <= 239) return 3; // D if (first >= 240 && first <= 255) return 4; // E return -1; } // 判断是否私有IP bool is_private_ip(const vector<string>& ip) { int a = stoi(ip[0]), b = stoi(ip[1]); if (a == 10) return true; if (a == 172 && b >= 16 && b <= 31) return true; if (a == 192 && b == 168) return true; return false; } int main() { string line; int cnt[7] = {0}; // A, B, C, D, E, 错误, 私有 while (getline(cin, line)) { if (line.empty()) continue; size_t pos = line.find('~'); if (pos == string::npos) continue; string ip_str = line.substr(0, pos); string mask_str = line.substr(pos + 1); vector<string> ip = split(ip_str, '.'); vector<string> mask = split(mask_str, '.'); // 特殊判断 if (ip.size() != 4) { cnt[5]++; continue; } if (ip[0] == "0" || ip[0] == "127") continue; if (!is_valid_ip(ip) || !is_valid_mask(mask)) { cnt[5]++; continue; } int t = get_ip_type(ip); if (t >= 0 && t <= 4) cnt[t]++; if (is_private_ip(ip) && t >= 0 && t <= 2) cnt[6]++; } for (int i = 0; i < 7; ++i) { cout << cnt[i]; if (i != 6) cout << " "; } cout << endl; return 0; }