题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
#include <iostream> #include <string> #include <vector> #include <bitset> using namespace std; int main() { string str,str1,str2,str3,str4; int pos; vector<int> num1,num2; int cout_a=0,cout_b=0,cout_c=0,cout_d=0,cout_e=0,cout_err=0,cout_err_now=0,cout_private=0; while (getline(cin,str)) { // 注意 while 处理多个 case pos=str.find('~'); str1.append(str,0,pos); str2.append(str,pos+1,str.size()-1); for(int i=0;i<str1.size();i++){ if(str1[i]!='.'){ str3+=str1[i]; } else if(str1[i]=='.'&&str3!=""){ //处理19..0. num1.push_back(stoi(str3)); str3=""; } } if(str3!="") num1.push_back(stoi(str3));//添加ip地址最后一位 str1=""; str3=""; for(int j=0;j<str2.size();j++){ if(str2[j]!='.'){ str4+=str2[j]; } else if(str2[j]=='.'&&str4!=""){ //处理19..0. num2.push_back(stoi(str4)); str4=""; } } if(str4!="") num2.push_back(stoi(str4));//添加ip地址最后一位 str2=""; str4=""; //判断子网掩码 if(num2.size()==4){ bitset<8> bits1(num2[0]); bitset<8> bits2(num2[1]); bitset<8> bits3(num2[2]); bitset<8> bits4(num2[3]); string str_1=bits1.to_string(); string str_2=bits2.to_string(); string str_3=bits3.to_string(); string str_4=bits4.to_string(); string str_5=str_1+str_2+str_3+str_4; int pos=str_5.find("01"); if(pos!=-1 || \ (num2[0]==255&&num2[1]==255&&num2[2]==255&&num2[3]==255) || \ (num2[0]==0 &&num2[1]==0 &&num2[2]==0 &&num2[3]==0) ){//如果找到01 cout_err_now=1;//cout_err_now代表本次子网掩码是否错误 } } //判断a~e 有效ip if(num1.size()==4 && cout_err_now==0 && \ num1[0]>=1&&num1[0]<=126 && \ num1[1]>=0&&num1[1]<=255 && \ num1[2]>=0&&num1[2]<=255 && \ num1[3]>=0&&num1[3]<=255 ){ cout_a++; } else if(num1.size()==4 && cout_err_now==0 && \ num1[0]>=128&&num1[0]<=191 && \ num1[1]>=0&&num1[1]<=255 && \ num1[2]>=0&&num1[2]<=255 && \ num1[3]>=0&&num1[3]<=255 ){ cout_b++; } else if(num1.size()==4 && cout_err_now==0 && \ num1[0]>=192&&num1[0]<=223 && \ num1[1]>=0&&num1[1]<=255 && \ num1[2]>=0&&num1[2]<=255 && \ num1[3]>=0&&num1[3]<=255 ){ cout_c++; } else if(num1.size()==4 && cout_err_now==0 && \ num1[0]>=224&&num1[0]<=239 && \ num1[1]>=0&&num1[1]<=255 && \ num1[2]>=0&&num1[2]<=255 && \ num1[3]>=0&&num1[3]<=255 ){ cout_d++; } else if(num1.size()==4 && cout_err_now==0 && \ num1[0]>=240&&num1[0]<=255 && \ num1[1]>=0&&num1[1]<=255 && \ num1[2]>=0&&num1[2]<=255 && \ num1[3]>=0&&num1[3]<=255 ){ cout_e++; } else if(num1[0]==0 || num1[0]==127 ){//注意这里一定不能加num1.size()==4 && cout_err_now==0 因为这个不在计数范围内 } else{ cout_err++; } //判断私有ip if(num1.size()==4 && cout_err_now==0 && \ (num1[0]==10 && \ num1[1]>=0 && num1[1]<=255 && \ num1[2]>=0 && num1[2]<=255 && \ num1[3]>=0 && num1[3]<=255)|| \ (num1[0]==172 && \ num1[1]>=16 && num1[1]<=31 && \ num1[2]>=0 && num1[2]<=255 && \ num1[3]>=0 && num1[3]<=255)|| \ (num1[0]==192 && \ num1[1]==168 && \ num1[2]>=0 && num1[2]<=255 && \ num1[3]>=0 && num1[3]<=255) ){ cout_private++; } num1={}; num2={}; cout_err_now=0;//本次的判断完,cout_err_now清零 } cout<< cout_a <<" "<< cout_b<<" "<<cout_c<<" "<<cout_d<<" "<<cout_e<<" "<<cout_err<<" "<<cout_private<<endl; } // 64 位输出请用 printf("%lld")
解题思路:
关于输入输出:输入为一行字符串,可以直接用getline(cin,str)
关于判断ip类型:先把字符串的ip和子网掩码分开,利用find('~')即可。然后把ip的每个.隔开的字符串变成int,利用stoi(str),用vector保存每部分的数,然后比较其范围。
关于判断子网掩码类型:同理把每个.隔开的字符串变成int,然后根据子网掩码的特点,前面是连续1后面连续0,需要把int转化成二进制,可以利用bitset<8> bits(n),然后把二进制转成字符串,利用bits.to_string(),最后搜索里面有没有“01”出现。