题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
#include <iostream> #include <string> #include <sstream> #include <vector> #include <bitset> using namespace std; int isSub(string sub) { //判断子网掩码是否正确 stringstream ss(sub); string t; int first_1 = 0; int first_0 = 0; while (getline(ss, t, '.')) { if (t.size() == 0) { return 0; } int num = stoi(t); bitset<8> bin_n(num); string bins = bin_n.to_string(); for (int i = 0; i < 8; i++) { if ((!first_1 && bins[i] == '0') || (first_0 && bins[i] == '1')) return 0; else if (!first_1 && bins[i] == '1') { first_1 = 1; } else if (first_1 && !first_0 && bins[i] == '0') { first_0 = 1; } } } if (first_0 == 0 || first_1 == 0) return 0; else return 1; } //返回-1 表示子网掩码错误, 返回 0 表示不是A类地址, 返回1 表示是A类地址 int isNetA(string addr, string sub) { int low[] = {1, 0, 0, 0}; int top[] = {126, 255, 255, 255}; int lowp[] = {10, 0, 0, 0}; int topp[] = {10, 255, 255, 255}; //先判断子网掩码是否正确 if (!isSub(sub)) return -1; stringstream ss(addr); string t; int idx = 0; int isPriv = 1; while (getline(ss, t, '.')) { if (t.size() == 0) { return -1; } int num = stoi(t); if (num < 0) return -1; if (num < low[idx] || num > top[idx]) { return 0; } if (isPriv && (num < lowp[idx] || num > topp[idx])) { isPriv = 0; } idx += 1; } if (isPriv) return 2; return 1; } //返回-1 表示子网掩码错误, 返回 0 表示不是B类地址, 返回1 表示是B类地址 int isNetB(string addr, string sub) { int low[] = {128, 0, 0, 0}; int top[] = {191, 255, 255, 255}; int lowp[] = {172, 16, 0, 0}; int topp[] = {172, 31, 255, 255}; //先判断子网掩码是否正确 if (!isSub(sub)) return -1; stringstream ss(addr); string t; int idx = 0; int isPriv = 1; while (getline(ss, t, '.')) { if (t.size() == 0) { return -1; } int num = stoi(t); if (num < 0) return -1; if (num < low[idx] || num > top[idx]) { return 0; } if (isPriv && (num < lowp[idx] || num > topp[idx])) { isPriv = 0; } idx += 1; } if (isPriv) return 2; return 1; } //返回-1 表示子网掩码错误, 返回 0 表示不是C类地址, 返回1 表示是C类地址 int isNetC(string addr, string sub) { int low[] = {192, 0, 0, 0}; int top[] = {223, 255, 255, 255}; int lowp[] = {192, 168, 0, 0}; int topp[] = {192, 168, 255, 255}; //先判断子网掩码是否正确 if (!isSub(sub)) return -1; stringstream ss(addr); string t; int idx = 0; int isPriv = 1; while (getline(ss, t, '.')) { if (t.size() == 0) { return -1; } int num = stoi(t); if (num < 0) return -1; if (num < low[idx] || num > top[idx]) { return 0; } if (isPriv && (num < lowp[idx] || num > topp[idx])) { isPriv = 0; } idx += 1; } if (isPriv) return 2; return 1; } //返回-1 表示子网掩码错误, 返回 0 表示不是D类地址, 返回1 表示是D类地址 int isNetD(string addr, string sub) { int low[] = {224, 0, 0, 0}; int top[] = {239, 255, 255, 255}; //先判断子网掩码是否正确 if (!isSub(sub)) return -1; stringstream ss(addr); string t; int idx = 0; while (getline(ss, t, '.')) { if (t.size() == 0) { return -1; } int num = stoi(t); if (num < 0) return -1; if (num < low[idx] || num > top[idx]) { return 0; } idx += 1; } return 1; } //返回-1 表示子网掩码错误, 返回 0 表示不是E类地址, 返回1 表示是E类地址 int isNetE(string addr, string sub) { int low[] = {240, 0, 0, 0}; int top[] = {255, 255, 255, 255}; //先判断子网掩码是否正确 if (!isSub(sub)) return -1; stringstream ss(addr); string t; int idx = 0; while (getline(ss, t, '.')) { if (t.size() == 0) { return -1; } int num = stoi(t); if (num < 0) return -1; if (num < low[idx] || num > top[idx]) { return 0; } idx += 1; } return 1; } int main() { // int an = 0; int bn = 0; int cn = 0; int dn = 0; int en = 0; int errn = 0; int pn = 0; string str; while (getline(cin, str)) { stringstream ss(str); vector<string> tokens; string t; while (getline(ss, t, '~')) { if (t.size() == 0) { continue; } tokens.push_back(t); } if(tokens[0].substr(0, tokens[0].find('.'))=="0" || tokens[0].substr(0, tokens[0].find('.'))=="127") continue; int resa = isNetA(tokens[0], tokens[1]); if(resa == 2){ //cout << "resa==2 : " << tokens[0] << "~" <<tokens[1] << endl; an ++; pn ++; continue; }else if(resa == 1){ //cout << "resa==1 : " << tokens[0] << "~" <<tokens[1] << endl; an ++; continue; } int resb = isNetB(tokens[0], tokens[1]); if(resb == 2){ //cout << "resb==2 : " << tokens[0] << "~" <<tokens[1] << endl; bn ++; pn ++; continue; } else if(resb == 1){ //cout << "resb==1 : " << tokens[0] << "~" <<tokens[1] << endl; bn ++; continue; } int resc = isNetC(tokens[0], tokens[1]); if(resc == 2){ //cout << "resc==2 : " << tokens[0] << "~" <<tokens[1] << endl; cn ++; pn ++; continue; } else if(resc == 1){ //cout << "resc==1 : " << tokens[0] << "~" <<tokens[1] << endl; cn ++; continue; } int resd = isNetD(tokens[0], tokens[1]); if(resd == 1){ //cout << "resd==1 : " << tokens[0] << "~" <<tokens[1] << endl; dn ++; continue; } int rese = isNetE(tokens[0], tokens[1]); if(rese == 1){ //cout << "rese==1 : " << tokens[0] << "~" <<tokens[1] << endl; en ++; continue; } //cout << "error : " << tokens[0] << "~" <<tokens[1] << endl; errn ++; } cout << an << " " << bn << " " << cn << " " << dn << " " <<en << " " << errn << " " << pn; return 0; } // 64 位输出请用 printf("%lld")
可以将判断每个网络地址类型的函数写成一个,然后根据传入的地址范围进行判断