原思路在这里https://blog.nowcoder.net/n/ebd233f92fc840a19b8bdea8d
d178d25?f=comment,参考他的,不过他的解题有一些小bug:应该先判断ip地址首位是否是0/127,如果是的话就直接跳过,不用判断计数。
#include<iostream> #include<string> #include<sstream> #include<vector> using namespace std; bool judge_ip(string ip) { int j = 0; istringstream iss(ip); string seg; while (getline(iss, seg, '.')) if (++j > 4 || seg.empty() || stoi(seg) > 255||stoi(seg)<0) //若段数超出范围、有空、超出范围,则不是合法ip return false; return j == 4; //段数是否小于4 } 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] <= 31)) return true; if (v[0] == 192 && v[1] == 168) return true; return false; } bool is_mask(string ip) { istringstream iss(ip); //从字符串中提取格式化数据 string seg; unsigned b = 0; while (getline(iss, seg,'.')) b = (b << 8) + stoi(seg);//以.分隔,将字符串转化为整数 if (!b) return false; //如果全是0 b = ~b + 1; if (b == 1) return false; //如果全是1 if ((b & (b - 1)) == 0) return true; //这里判断是否满足前面连续是1、后面全是0 return false; } int main() { string input; int a = 0, b = 0, c = 0, d = 0, e = 0, err = 0, p = 0; while (cin >> input) { //按行输入 istringstream is(input); string add; vector<string> v; while (getline(is, add, '~')) v.push_back(add); //以~为分割,将每行的ip和掩码放进数组 int first = stoi(v[0].substr(0, v[0].find_first_of('.')));//寻找IP地址的首位,放入first if(first==0||first==127)continue;//应该先判断ip地址首位是否是0/127,是的话就直接跳过,否则才分类计数 if (!judge_ip(v[1]) || !is_mask(v[1])) err++; else { if (!judge_ip(v[0])) err++; else { if (is_private(v[0])) p++; 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++; } } } cout << a << " " << b << " " << c << " " << d << " " << e << " " << err << " " << p << endl; return 0; }