#include <cctype> #include <iostream> #include<string> #include<vector> #include <algorithm> using namespace std; //合法的掩码可能出现的数字(前一后零) int legelNum[9] = {255, 254, 252, 248, 240, 224, 192, 128, 0}; //分割字符串 void separate(const string str1, vector<string>& strvecIP, vector<string>& strvecCode) { //两遍相同操作分别把IP和掩码分割存储 string strIP = str1.substr(0, str1.find('~')); int posl = 0, pos = strIP.find('.'); while (pos != string::npos) { strvecIP.push_back(strIP.substr(posl, pos - posl)); posl = pos + 1; pos = strIP.find('.',posl); } strvecIP.push_back(strIP.substr(posl)); // string strCode = str1.substr(str1.find('~') + 1); posl = 0, pos = strCode.find('.'); while (pos != string::npos) { strvecCode.push_back(strCode.substr(posl, pos - posl)); posl = pos + 1; pos = strCode.find('.',posl); } strvecCode.push_back(strCode.substr(posl)); } //判断IP合法性 bool IPcorrection(const vector<string>strvecIP) { //不合法情形只有分隔符间没数的情形 if (strvecIP.size() == 4) { for (int i = 0; i < 4; i++) { if (strvecIP[3 - i].size() == 0 || strvecIP[3 - i].size() > 3) { return false; } } } return true; } //判断掩码合法性 bool Codecorrection(const vector<string>strvecCode) { //如果IP地址是本网或者巡回自检,则即使掩码错了也不计入错误数,及其抽象,该判断放到main函数去了 if (strvecCode.size() != 4) { return false; } else { bool flag = true;//仅当第后面的数全为0时前面可能有不为255的数 for (int i = 0; i < 4; i++) { if (strvecCode[i].size() == 0 || strvecCode[i].size() > 3) { return false;//输入不合法的情形,没数或者超过255 } else { if(stoi(strvecCode[0])==0||stoi(strvecCode[3])==255){ return false;//全0和全1的情形 } if (flag) { int num = stoi(strvecCode[3 - i]); if (find(legelNum, legelNum + 9, num) != legelNum + 9) { //判断数字合法 if (num != 0) { flag = false;//不为0则前面必须全是255 } } else { return false;//数字不合法 } } else { //后面已经有非0数了,前面必须全是255 if (stoi(strvecCode[3 - i]) != 255) { return false; } } } } } return true; } //判断类别 int kind_Decide(const vector<string>strvecIP){ int num=stoi(strvecIP[0]); if(1<=num&&num<=126){ return 0; } else if(128<=num&&num<=191){ return 1; } else if(192<=num&&num<=223){ return 2; } else if(224<=num&&num<=239){ return 3; } else if(240<=num&&num<=255){ return 4; } else{ return -1;//本网和巡回自检 } } //判断私网 bool private_Decide(const vector<string>strvecIP){ int num0=stoi(strvecIP[0]),num1=stoi(strvecIP[1]); if(num0==10){ return true; } if(num0==172&16<=num1&&num1<=31){ return true; } if(num0==192&&num1==168){ return true; } return false; } int main() { string str1; int result[7]={0,0,0,0,0,0,0}; while (getline(cin, str1)) { // 注意 while 处理多个 case vector<string>strvecIP,strvecCode; separate(str1,strvecIP,strvecCode); if(!IPcorrection(strvecIP)||!Codecorrection(strvecCode)&&stoi(strvecIP[0])!=0&&stoi(strvecIP[0])!=127){ result[5]++; } else{ if(kind_Decide(strvecIP)!=-1){ result[kind_Decide(strvecIP)]++; } if(private_Decide(strvecIP)){ result[6]++; } } } for(int i=0;i<7;i++){ cout << result[i] << ' '; } }