本题将会给出
条地址信息,确切数字未知,您需要一直读入直到文件结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每条地址信息描述如下:
在一行上先输入一个字符串,代表
地址;随后,在同一行输入一个字符串,代表子网掩码;使用
分隔。
在一行上输出七个整数,分别代表ABCDE类地址的数量、错误
或错误子网掩码的数量、私有
的数量。
10.70.44.68~1.1.1.5 1.0.0.1~255.0.0.0 192.168.0.2~255.255.255.0 19..0.~255.255.255.0
1 0 1 0 0 2 1
对于第一条地址信息,
是其
地址,
是其子网掩码;该条地址的子网掩码非法。
对于第二条地址信息,
地址和子网掩码均无误,且属于A类地址。
对于第三条地址信息,
地址和子网掩码均无误,且属于C类地址,同时属于私有
地址。
对于第四条地址信息,
地址非法。
0.201.56.50~255.255.255.0 127.201.56.50~255.255.111.255
0 0 0 0 0 0 0
对于第一、二条地址信息,均属于上方提示中提到的特殊
地址,不需要处理,直接跳过。
特别地,第二条地址的子网掩码是非法的。但是因为该条为特殊
地址,此优先级更高,所以不进入统计。
#include <stdio.h> int main() { unsigned int IP[8] = {-1}; unsigned int IPType[16] = {0}; unsigned int SubnetMask[31] = {0xffffffff}; int Statistics[7] = {0}; int ErrorFlag = 0; int i = 0; memset(IP,-1,sizeof(unsigned int)*8); memset(SubnetMask,0xffffffff,sizeof(unsigned int)*31); memset(Statistics,0,sizeof(int)*7); for(int j=0; j<31; j++) { SubnetMask[j] = SubnetMask[j]<<(j+1); } IPType[0] = 0x01000000; IPType[1] = 0x7effffff; IPType[2] = 0x80000000; IPType[3] = 0xbfffffff; IPType[4] = 0xc0000000; IPType[5] = 0xdfffffff; IPType[6] = 0xe0000000; IPType[7] = 0xf0000000; IPType[8] = 0xf0000000; IPType[9] = 0xffffffff; IPType[10] = 0x0a000000; IPType[11] = 0x0affffff; IPType[12] = 0xac100000; IPType[13] = 0xac1fffff; IPType[14] = 0xc0a80000; IPType[15] = 0xc0a8ffff; while(scanf("%d",&IP[i])!=EOF) { //printf("%d ",IP[i]); if(getchar()!='\n') { i++; } else { i = 0; for(int j=0; j<8; j++) { if(IP[j]==-1) { Statistics[5]++; ErrorFlag = 1; break; } } if(ErrorFlag == 0) { IP[0] = (IP[0]<<24)|(IP[1]<<16)|(IP[2]<<8)|(IP[3]<<0); IP[4] = (IP[4]<<24)|(IP[5]<<16)|(IP[6]<<8)|(IP[7]<<0); if(SubnetMask[31-(__builtin_popcount(IP[4]))]!=IP[4]) { Statistics[5]++; ErrorFlag = 1; } else { if(IP[0]>=IPType[0] && IP[0]<=IPType[1]) { Statistics[0]++; } else if(IP[0]>=IPType[2] && IP[0]<=IPType[3]) { Statistics[1]++; } else if(IP[0]>=IPType[4] && IP[0]<=IPType[5]) { Statistics[2]++; } else if(IP[0]>=IPType[6] && IP[0]<=IPType[7]) { Statistics[3]++; } else if(IP[0]>=IPType[8] && IP[0]<=IPType[9]) { Statistics[4]++; } if((IP[0]>=IPType[10] && IP[0]<=IPType[11]) || (IP[0]>=IPType[12] && IP[0]<=IPType[13]) || (IP[0]>=IPType[14] && IP[0]<=IPType[15]) ) { Statistics[6]++; } } } ErrorFlag = 0; //printf(" "); memset(IP,-1,sizeof(int)*8); } } for(int j=0; j<6; j++) { printf("%d ",Statistics[j]); } printf("%d",Statistics[6]); return 0; }
#include <iostream> #include <string> #include <vector> #include <sstream> using namespace std; constexpr int A = 0, B = 1, C = 2, D = 3, E = 4, error = 5, privated = 6, other = 7; void split(string str, char ch, vector<string>& re) { re.clear(); string temp; for (char c : str) { if (c != ch) { temp += c; } else { re.push_back(temp); temp.clear(); } } re.push_back(temp); } struct IP { unsigned char add[4]; bool mask; unsigned int data() { unsigned int i = (unsigned int)add[0]; i <<= 8; i += add[1]; i <<= 8; i += add[2]; i <<= 8; i += add[3]; return i; } bool load(string s) { // return false means error vector<string> sp; split(s, '.', sp); stringstream ss; unsigned int i = 0; for (string& t_str : sp) { if (i > 4 || t_str.empty()) { return false; } else { long long t; ss << t_str; ss >> t; ss.clear(); if (t > 255 || t < 0) { return false; } else { add[i] = (unsigned char)t; } } i++; } // 判断是否能成为掩码 // 使用int保存4个uchar i = data(); if(i == 0 || i == -1) { mask = false; return true; } bool b = false; for (int l = 0; l < 32; l++) { mask = true; if (!(i & 1) && !b) { ; } else if (!(i & 1) && b) { mask = false; break; } else if ((i & 1) && !b) { b = true; } else if ((i & 1) && b) { ; } i >>= 1; } return true; } }; using Mask = IP; int ipClsCount(string str, bool& b) { // 先分析ip vector<string> ips; split(str, '~', ips); IP ip; Mask mask; if ((!mask.load(ips[1]) | !ip.load(ips[0]) ) || !mask.mask) { // cout << ips[0] << '\t' << ips[1] << ' ' << mask.mask << endl; return error; } // Other? if (ip.add[0] == 0 || ip.add[0] == 127) { return other; } // Private? if (ip.add[0] == 10) { b = true; } else if (ip.add[0] == 172) { if (ip.add[1] >= 16 && ip.add[1] <= 31) { b = true; } else { b = false; } } else if (ip.add[0] == 192) { if (ip.add[1] == 168) { b = true; } } // A B C D E? if (ip.add[0] <= 126) { return A; } else if (ip.add[0] <= 191) { return B; } else if (ip.add[0] <= 223) { return C; } else if (ip.add[0] <= 239) { return D; } else { return E; } } int main() { string str; while (getline(cin, str)) { int ipCls[8] = {0}; do { bool isExPrivated = false; ipCls[ipClsCount(str, isExPrivated)]++; if (isExPrivated) { ipCls[privated]++; } } while (getline(cin, str) && str != ""); for (int i = 0; i < 6; i++) { cout << ipCls[i] << ' '; } cout << ipCls[6]; } return 0; }
//常规思路,一步一步拆解判断、检查 #include <iostream> #include <string> #include <vector> #include <cstring> #include <cmath> /* 运行时间:5ms 超过35.31%用C++提交的代码 占用内存:400KB 超过79.35%用C++提交的代码 */ using namespace std; // 将点分十进制的ip地址转换成 255进制的 long long 整数,用于判断ip处于哪个分类区间 long long A1 = 1 * pow(255,3), A2 = 126 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255; long long B1 = 128 * pow(255,3), B2 = 191 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255; long long C1 = 192 * pow(255,3), C2 = 223 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255; long long D1 = 224 * pow(255,3), D2 = 239 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255; long long E1 = 240 * pow(255,3), E2 = 255 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255; long long priv1 = 10 * pow(255,3), priv12 = 10 * pow(255,3) + 255 * pow(255,2) + 255 * pow(255,1) + 255; long long priv2 = 172 * pow(255,3) + 16 * pow(255, 2), priv22 = 172 * pow(255,3) + 31 * pow(255,2) + 255 * pow(255,1) + 255; long long priv3 = 192* pow(255,3) + 168 * pow(255, 2), priv32 = 192 * pow(255,3) + 168 * pow(255,2) + 255 * pow(255,1) + 255; //按'.'符号 分割ip 或者 mask void fillDivideString(vector<string>& divided, string& str) { //1. 3个点分,4个数字,所以按 . 来分割ip char local_str[str.length()+1]; memcpy(local_str, str.c_str(), str.length()+1); const char* del = "."; char* tmp = strtok(local_str, del); while(nullptr != tmp) { if(string(tmp).length() > 0) { //tmp可能为空 divided.push_back(tmp); } tmp = strtok(nullptr, del); } return; } //题目意思 //如果输入的一行中,Ip或mask是错误的,那么这次的输入行归为 错误IP或错误掩码 //所以,如果掩码错误或者ip错误,两者之一就可以归入,另一个不再检查 //先检查mask或先检查ip都一样 void classifyIpMask(vector<int>& count, string& ip, string& mask) { //先检查mask合法性,如果mask非法,那么不再检查ip, vector<string> mask_divided; bool isvalid = true; //mask是否合法 fillDivideString(mask_divided, mask); if(mask_divided.size() != 4) { count[5]++; //错误掩码 +1 } else { //检查掩码的二进制表示,前面是连续的1,后面全是0 bool foundZero = false; //辅助检查是否全0 bool foundOne = false; //辅助检查啥否全1 for(int i = 0; i < mask_divided.size(); i++) { int m = stoi(mask_divided[i]); int offset = 7; //注意每个part只有8位,所以最大偏移是 7 while(offset >= 0 && isvalid) { if((m >> offset) & 1) { //该bit是 1 foundOne = true; if(foundZero) { isvalid = false; break; } } else { //否则 该bit是0 if(!foundZero) { foundZero = true; } } offset--; } //违反:前面是连续的1,后面全是0 if(!isvalid) { count[5]++; break; } } //违反:全1或者全0 if(isvalid && (!foundZero || !foundOne)) { isvalid = false; count[5]++; } } //如果前面mask检查好合法,继续检查ip if(isvalid) { vector<string> ip_divided; fillDivideString(ip_divided, ip); if(ip_divided.size() != 4) { //不合法 count[5]++; //错误IP地址 +1 } else { //ip分类 long long sum = 0; for(int i = 0; i < ip_divided.size(); i++) { //FIX ME: 实际上这里还需要检查 stoi 的参数是否是数字字符串 long long n = stoi(ip_divided[i]); sum += (n * pow(255, 3-i)); //转成一个255进制的数 } if(A1 <= sum && sum <= A2) { //A类 count[0]++; } else if(B1 <= sum && sum <= B2) { //B类 count[1]++; } else if(C1 <= sum && sum <= C2) { //C类 count[2]++; } else if(D1 <= sum && sum <= D2) { //D类 count[3]++; } else if(E1 <= sum && sum <= E2) { //E类 count[4]++; } if((priv1 <= sum && sum <= priv12) //私有IP || (priv2 <= sum && sum <= priv22) || (priv3 <= sum && sum <= priv32)) { count[6]++; } } } } int main() { string ip_and_mask; vector<int> count(7, 0); while(cin >> ip_and_mask) { int pos = ip_and_mask.find_first_of('~'); string ip = ip_and_mask.substr(0,pos); string mask = ip_and_mask.substr(pos+1); classifyIpMask(count, ip, mask); } for(int i = 0; i < count.size(); i++) { cout << count[i]; if(i < count.size()-1) cout << " "; } cout << endl; }
for(int i=left;i<right;i++){//将数字拼成字符串 stemp+=str[i]; }
temp=stoi(stemp); vv.push_back(temp);
if(left==right && right!=str.size()-1){//如果出现连续字符时,为错误IP或掩码 err++; iserr=true; break; }
void vld(vector<int> vv,bool &iserr){ int zero=0,one=32; long long int sum=0; if(vv[4]==0 || vv[7]==255){ err++; iserr=true; return ; }//全0全1直接非法 for(int i=4;i<8;i++){ int temp=vv[i]; sum=(sum<<8)+temp;//将掩码拼在一起 } for(int i=0;i<32;i++){ if(sum%2==1&&one==32) one-=i+1;//最右的1 if(sum%2==0) zero++;//0的数量 sum=sum/2; } if((zero+one)!=31){//如果0都在1的右边,则0和1的和为31,否则为非法掩码 err++; iserr=true; return ; } else if(vv[0]==0 || vv[0]==127){//判断是否为无效IP iserr=true; return; } return ; }全部代码如下,仅供参考。
#include<iostream> #include<vector> using namespace std; int a=0,b=0,c=0,d=0,e=0,err=0,prv=0; bool iserr=false; void ip(int num){ if(num>=1 && num<=126) a++; else if(num>=128 && num<=191) b++; else if(num>=192 && num<=223) c++; else if(num>=224 && num<=239) d++; else if(num>=240 && num<=255) e++; return; } void prvip(int fir,int sec){ if(fir==10) prv++; else if(fir==172 && sec>=16 && sec<=31) prv++; else if(fir==192 && sec==168) prv++; return; } void vld(vector<int> vv,bool &iserr){ int zero=0,one=32; long long int sum=0; if(vv[4]==0 || vv[7]==255){ err++; iserr=true; return ; }//全0全1直接非法 for(int i=4;i<8;i++){ int temp=vv[i]; sum=(sum<<8)+temp;//将掩码拼在一起 } for(int i=0;i<32;i++){ if(sum%2==1&&one==32) one-=i+1;//最右的1 if(sum%2==0) zero++;//0的数量 sum=sum/2; } if((zero+one)!=31){//如果0都在1的右边,则0和1的和为31,否则为非法掩码 err++; iserr=true; return ; } else if(vv[0]==0 || vv[0]==127){//判断是否为无效IP iserr=true; return; } return ; } int main(){ int temp; int left=0,right;//left为每个数字的头,right为每个数字的尾后一位 string str,stemp; vector<int> vv; while(cin>>str) { for(right=0;right<str.size();right++){ if(str[right]=='.' || str[right]=='~' || right==str.size()-1){//当right为字符或者为最后一位时读取数据 if(left==right && right!=str.size()-1){//如果出现连续字符时,为错误IP或掩码 err++; iserr=true; break; } if(right==str.size()-1)//当right为最后一位时,+1则为尾后一位; right++; for(int i=left;i<right;i++){//将数字拼成字符串 stemp+=str[i]; } temp=stoi(stemp); vv.push_back(temp); stemp.clear(); left=right+1;//更新left } } if(!iserr){ vld(vv,iserr); if(!iserr){ ip(vv[0]); prvip(vv[0],vv[1]); } } str.clear(); vv.clear(); left=0; iserr=false; } cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<" "<<err<<" "<<prv<<endl; return 0; }
#include<iostream> #include<vector> #include<string> using namespace std; vector<int> parser(string& s) { vector<int> nums; int i = 0, j = 0; while(j < s.size()) { if(s[j]!='.') { ++j; } else { if(i==j) { nums.push_back(-1); } else { nums.push_back(atoi(s.substr(i, j-i).c_str())); } ++j; i = j; } } if(i==j) { nums.push_back(-1); } else { nums.push_back(atoi(s.substr(i, j-i).c_str())); } return nums; } bool isOk(vector<int>& nums) { if(nums.size() != 4) return false; for(int i=0; i<4; ++i) { if(nums[i] < 0 || nums[i] > 255) return false; } return true; } bool isMask(vector<int>& nums) { unsigned num = 0; for(unsigned n : nums) { num <<= 8; num |= n; } if(num == 0) return false; unsigned bit = (1<<31); while(bit) { if((num&bit) == 0) break; bit >>= 1; } if(bit == 0) return false; while(bit) { if((num&bit) != 0) return false; bit >>= 1; } return true; } int main() { int A=0, B=0, C=0, D=0, E=0, F=0, G=0; string str; while(cin >> str) { int i=0; while(str[i]!='~') ++i; string ip = str.substr(0, i); string mask = str.substr(i+1, str.size()-i); vector<int> nums = parser(ip); vector<int> masks = parser(mask); if(isOk(nums) && isOk(masks) && isMask(masks)) { if(nums[0] != 127 && nums[0] != 0) { if(nums[0] >= 1 && nums[0] <= 126) { ++A; } else if(nums[0] >= 128 && nums[0] <= 191) { ++B; } else if(nums[0] >= 192 && nums[0] <= 223) { ++C; } else if(nums[0] >= 224 && nums[0] <= 239) { ++D; } else if(nums[0] >= 240 && nums[0] <= 255){ ++E; } } if(nums[0] == 10) ++G; if(nums[0] == 192 && nums[1] == 168) ++G; if(nums[0] == 172 && nums[1] >=16 && nums[1] <= 31) ++G; } else { ++F; } } cout << A <<" "<< B <<" "<< C <<" "<< D <<" " << E <<" "<< F <<" "<< G << endl; return 0; }
#include <iostream> #include <string> #include <string.h> #include <stdio.h> using namespace std; uint32_t ip_str2bit(string s) { uint32_t tmp = 0; int i; i= 0; uint32_t r = 0; while (i < s.length()) { if (s[i] == '.') { r = (r << 8) + tmp; tmp = 0; } else { tmp = tmp * 10 + (s[i] - '0'); } ++i; } r = (r << 8) + tmp; return r; } void classify(string s, int r[]) { size_t pos = s.find('~'); string s1 = s.substr(0, pos); string s2 = s.substr(pos + 1, s.length() - pos); uint32_t b1 = ip_str2bit(s1); uint32_t b2 = ip_str2bit(s2); /* classify Mask */ if (b2 == 0x00000000 || b2 == 0xFFFFFFFF) { ++r[6]; return; } b2 = ~b2; if (b2 & (b2 + 1)) { ++r[6]; return; } /* classify IP */ // 0.*.*.* unknown network if (!((b1 & 0xFF000000) ^ 0x00000000)) return; // 127.*.*.* unknown network if (!((b1 & 0xFF000000) ^ 0x7F000000)) return; // 10.*.*.* private network if (!((b1 & 0xFF000000) ^ 0x0A000000)) ++r[7]; // 172.16.0.0 - 172.31.255.255 private network if (!((b1 & 0xFFF00000) ^ 0xAC100000)) ++r[7]; // 192.168.*.* private network if (!((b1 & 0xFFFF0000) ^ 0xC0A80000)) ++r[7]; // Type A if (!((b1 & 0x80000000) ^ 0x00000000)) ++r[1]; // Type B if (!((b1 & 0xC0000000) ^ 0x80000000)) ++r[2]; // Type C if (!((b1 & 0xE0000000) ^ 0xC0000000)) ++r[3]; // Type D if (!((b1 & 0xF0000000) ^ 0xE0000000)) ++r[4]; // Type E if (!((b1 & 0xF0000000) ^ 0xF0000000)) ++r[5]; } int main() { string s; int r[8] = {0}; while (getline(cin, s)) { classify(s, r); } for (int i = 1; i < 7; ++i) { cout << r[i] << ' '; } cout << r[7] << endl; return 0; }
输入利用scanf对格式的识别
n = scanf("%d.%d.%d.%d~%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3], &mask[0],&mask[1],&mask[2],&mask[3])) != EOF
返回值n为匹配到的整型数数量,n!=8说明读取错误,那么直接排除,不过要记得使用scanf("%s" , buf)把未读取到的字段清理一下,否则影响下次读取并死锁。当n=EOF=-1的时候,读到数据结尾,退出循环。
#include <stdio.h> #include <stdlib.h> #include <string.h> enum IPCLASS{ A = 0, B, C, D, E, ERR, PRI } ipclass; int main(){ int classcnt[7] = {0}; // ip分类计数 int n ; // 接收scanf返回值 int ip[4] = {0}; int mask[4] = {0}; while( (n = scanf("%d.%d.%d.%d~%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3], &mask[0],&mask[1],&mask[2],&mask[3])) != EOF ){ // 1.字段不对 if( n != 8 ){ // 不是ip错了就是mask错了 ipclass = ERR;classcnt[ipclass] ++; char buf[1024] ; scanf("%s", buf) ; //清理错误缓存 continue; } // 2.掩码是否为连续1与全0组合 int i = 0; int flags = 0; // 缺0字段标志,之后字段必须全0 int mask_err = 0; // 错误标志 if( (mask[0] == 0 && mask[1] == 0 && mask[2] == 0 && mask[3] == 0) || (mask[0] == 255 && mask[1] == 255 && mask[2] == 255 && mask[3] == 255)) mask_err = 1; else for( ; i < 4 ; i ++ ){ if( flags && mask[i] > 0 ){ mask_err = 1 ; break; } switch( mask[i] ){ case 255 : break; // 全1全0直接进入下一位判断 case 0 : case 254: case 252: case 248: case 240: case 224: case 192: case 128 : // 连1判断 flags = 1 ; break; default : mask_err = 1 ; break; // 其他情况 } } if( mask_err ){ // 掩码错误 ipclass = ERR ; classcnt[ipclass] ++ ; continue ; } // 3.ip判断 1)错误ip 小于0 大于255 , 2)ip分类 , 3)私有ip判断 // 1)错误ip int ip_err = 0 ; for(i=0;i<4;i++){ if( ip[i] > 255 || ip[i] < 0 ){ ip_err = 1 ; break ; } } if ( ip_err ){ // ip 错误 ipclass = ERR ; classcnt[ipclass] ++ ; continue ; } // 2)ip分类 if (ip[0] >= 1 && ip[0] <= 126) { ipclass = A ; classcnt[ipclass] ++ ; } else if (ip[0] >= 128 && ip[0] <= 191) { ipclass = B ; classcnt[ipclass] ++ ; } else if (ip[0] >= 192 && ip[0] <= 223) { ipclass = C ; classcnt[ipclass] ++ ; } else if (ip[0] >= 224 && ip[0] <= 239) { ipclass = D ; classcnt[ipclass] ++ ; } else if (ip[0] >= 240 && ip[0] <= 255) { ipclass = E ; classcnt[ipclass] ++ ; } // 私有ip if (ip[0] == 10 || (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) || (ip[0] == 192 && ip[1] == 168)) { ipclass = PRI ; classcnt[ipclass] ++ ; } } printf("%d %d %d %d %d %d %d\n" , classcnt[0] , classcnt[1] , classcnt[2] , classcnt[3] , classcnt[4] , classcnt[5] , classcnt[6]); return 0; }
#include "iostream" #include "vector" #include "algorithm" #include "string" using namespace std; string dec2x(int n, int x) { string ans = ""; do { int t = n % x; if (t >= 0 && t <= 9) ans += t + '0'; else ans += t - 10 + 'a'; n /= x; } while (n != 0); reverse(ans.begin(), ans.end()); return ans; } int x2dec(string s, int x) { int ans = 0; for (int i = 0; i < s.length(); i++) { if (s[i] >= '0'&&s[i] <= '9') ans = ans*x + s[i] - '0'; else { if (s[i] >= 'A'&&s[i] <= 'Z') s[i] += 'a' - 'A'; ans = ans*x + s[i] - 'a' + 10; } } return ans; } int s2i(string s) { int num=0; if(s.length()==0) return -1;//-1代表空字符串 for(int i=0;i<s.length();i++) { if(s[i]>='0'&&s[i]<='9') num=num*10+s[i]-'0'; } return num; } vector<string> s2n(string s,char c) { int pos=0; int nextpos=s.find(c,pos); vector<string> v; while(nextpos!=-1) { v.push_back(s.substr(pos,nextpos-pos)); pos=nextpos+1; nextpos=s.find(c,pos); } v.push_back(s.substr(pos,s.length()-pos));//最后没有字符c时必加 return v; } bool maskcheck(int amask[]) { bool flag=false; if(amask[0]==255) { if(amask[1]==255) { if(amask[2]==255) { if(amask[3]==254||amask[3]==252||amask[3]==248\ ||amask[3]==240||amask[3]==224||amask[3]==192\ ||amask[3]==128||amask[3]==0) flag=true; } else { if(amask[2]==254||amask[2]==252||amask[2]==248\ ||amask[2]==240||amask[2]==224||amask[2]==192\ ||amask[2]==128||amask[2]==0) if(amask[3]==0) flag=true; } } else { if(amask[1]==254||amask[1]==252||amask[1]==248\ ||amask[1]==240||amask[1]==224||amask[1]==192\ ||amask[1]==128||amask[1]==0) if(amask[2]==0&&amask[3]==0) flag=true; } } else { if(amask[0]==254||amask[0]==252||amask[0]==248\ ||amask[0]==240||amask[0]==224||amask[0]==192\ ||amask[0]==128||amask[0]==0) if(amask[1]==0&&amask[2]==0&&amask[3]==0) flag=true; } return flag; } bool ipcheck(int aip[]) { bool flag=false; if(aip[0]>=0&&aip[0]<=255) if(aip[1]>=0&&aip[1]<=255) if(aip[2]>=0&&aip[2]<=255) if(aip[3]>=0&&aip[3]<=255) flag=true; return flag; } int main() { string s; int A=0,B=0,C=0,D=0,E=0,err=0,self=0; while(getline(cin,s)) { if(s=="") break; int pos=s.find('~'); string ip=s.substr(0,pos); string mask=s.substr(pos+1,s.length()-pos-1); vector<string> vip=s2n(ip,'.'); vector<string> vmask=s2n(mask,'.'); int aip[4]={0}; int amask[4]={0}; for(int i=0;i<vmask.size();i++) { aip[i]=s2i(vip[i]); amask[i]=s2i(vmask[i]); } bool maskflag=maskcheck(amask); bool ipflag=ipcheck(aip); if(maskflag && ipflag) { if(aip[0]>=1&&aip[0]<=126) { A++; if(aip[0]==10) self++; } if(aip[0]>=128&&aip[0]<=191) { B++; if(aip[0]==172&&aip[1]>=16&&aip[1]<=31) self++; } if(aip[0]>=192&&aip[0]<=223) { C++; if(aip[0]==192&&aip[1]==168) self++; } if(aip[0]>=224&&aip[0]<=239) D++; if(aip[0]>=240&&aip[0]<=255) E++; } else err++; } cout<<A<<" "<<B<<" "<<C<<" "<<D<<" "<<E<<" "<<err<<" "<<self<<endl; }
#include"iostream" #include"string" using namespace std; int main() { string str; int Aip = 0; int Bip = 0; int Cip = 0; int Dip = 0; int Eip = 0; int Myip = 0; int errorip = 0; while(cin>>str) { int len = str.length(); int num[8] = {0}; //for(int i=0;i<len;i++) //int i=0; int flag = 0; while(1) { int i = 0; int num1 = 0; while(str[i]!='.') { i++; num1++; } if(num1==0) { break; } for(int a=0;a<num1;a++) { num[0]=num[0]*10+(str[a]-'0'); } int num2 = num1; i++; num2++; while(str[i]!='.') { i++; num2++; } if(num2==num1+1) { break; } for(int b=num1+1;b<num2;b++) { num[1]=num[1]*10+(str[b]-'0'); } int num3 = num2; i++; num3++; while(str[i]!='.') { i++; num3++; } if(num3==num2+1) { break; } for(int c=num2+1;c<num3;c++) { num[2]=num[2]*10+(str[c]-'0'); } int num4 = num3; i++; num4++; while(str[i]!='~') { i++; num4++; } if(num4==num3+1) { break; } for(int d=num3+1;d<num4;d++) { num[3]=num[3]*10+(str[d]-'0'); } //cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<" "<<num[3]; int num5 = num4; i++; num5++; while(str[i]!='.') { i++; num5++; } if(num5==num4+1) { break; } for(int e=num4+1;e<num5;e++) { num[4]=num[4]*10+(str[e]-'0'); } int num6 = num5; i++; num6++; while(str[i]!='.') { i++; num6++; } if(num6==num5+1) { break; } for(int f=num5+1;f<num6;f++) { num[5]=num[5]*10+(str[f]-'0'); } int num7 = num6; i++; num7++; while(str[i]!='.') { i++; num7++; } if(num7==num6+1) { break; } for(int g=num6+1;g<num7;g++) { num[6]=num[6]*10+(str[g]-'0'); } int num8 = num7; i++; num8++; while(i<len) { i++; num8++; } if(num8==num7+1) { break; } for(int h=num7+1;h<num8;h++) { num[7]=num[7]*10+(str[h]-'0'); } //cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<" "<<num[3] //<<" "<<num[4]<<" "<<num[5]<<" "<<num[6]<<" "<<num[7]; flag = 1; break; } if(flag == 0) { errorip++; continue; } unsigned int temp = 0; for(int j=4;j<8;j++) { temp=num[j]+(temp<<(8)); } temp = ~temp+1; if((temp&(temp-1))!=0) { errorip++; continue; } if((num[4]==0)||num[7]==255) { errorip++; continue; } int flag2 = 0; if((num[0]>=1)&&(num[0]<=126)) { flag2 = 1; Aip++; } else if((num[0]>=128)&&(num[0]<=191)) { flag2 = 1; Bip++; } else if((num[0]>=192)&&(num[0]<=223)) { flag2 = 1; Cip++; } else if((num[0]>=224)&&(num[0]<=239)) { flag2 = 1; Dip++; } else if((num[0]>=240)&&(num[0]<=255)) { flag2 = 1; Eip++; } if((num[0]==10) ||((num[0]==172)&&(num[1]>=16)&&(num[1]<=31)) ||((num[0]==192)&&(num[1]==168))) { flag2 = 1; Myip++; } if((num[4]==0)||(num[4]==127)) { continue; } } cout<<Aip<<" "<<Bip<<" "<<Cip<<" "<<Dip<<" "<<Eip<<" "<<errorip<<" "<<Myip; return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> //IP地址 #define A_ADDR_FROM 0x01000000 #define A_ADDR_TO 0x7EFFFFFF #define B_ADDR_FROM 0x80000000 #define B_ADDR_TO 0xBFFFFFFF #define C_ADDR_FROM 0xC0000000 #define C_ADDR_TO 0xDFFFFFFF #define D_ADDR_FROM 0xE0000000 #define D_ADDR_TO 0xEFFFFFFF #define E_ADDR_FROM 0xF0000000 #define E_ADDR_TO 0xFFFFFFFF //私网IP地址 #define PRIVATE_IP1_FROM 0x0A000000 #define PRIVATE_IP1_TO 0x0AFFFFFF #define PRIVATE_IP2_FROM 0xAC100000 #define PRIVATE_IP2_TO 0xAC1FFFFF #define PRIVATE_IP3_FROM 0xC0A80000 #define PRIVATE_IP3_TO 0xC0A8FFFF int main() { char ip[2000][200] = {0}; int b1,b2,b3,b4; int m1,m2,m3,m4; int count = 0; while(1){ if (scanf("%s",&ip[count][0]) != EOF){ count++; } else { break; } } int out[7]={0}; int i,ipValue; char* tmp; int ipFlg; int maskFlg; for (i=0; i<count; i++){ ipFlg = 0; maskFlg = 0; b1 = b2 = b3 = b4 = -1; m1 = m2 = m3 = m4 = -1; tmp = strtok(ip[i], "~"); sscanf(tmp,"%d.%d.%d.%d", &b1, &b2, &b3, &b4); tmp = strtok(NULL, "~"); sscanf(tmp,"%d.%d.%d.%d", &m1, &m2, &m3, &m4); if(b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1 || m1 == -1 || m2 == -1 || m3 == -1 || m4 == -1){ out[5]++; //IP地址格式错误 } else { ipValue = m1<<24 | m2<<16 | m3<<8 | m4; if (ipValue == 0xFFFFFFFF || ipValue == 0x0){ out[5]++; //非法掩码 } else if (((ipValue<<1)|ipValue)!=ipValue) { out[5]++; //非法掩码 } else{ ipValue = b1<<24 | b2<<16 | b3<<8 | b4; if(ipValue >= PRIVATE_IP1_FROM && ipValue <= PRIVATE_IP1_TO) { out[6]++; //私有IP1 } else if (ipValue >= PRIVATE_IP2_FROM && ipValue <= PRIVATE_IP2_TO) { out[6]++; //私有IP2 } else if (ipValue >= PRIVATE_IP3_FROM && ipValue <= PRIVATE_IP3_TO) { out[6]++; //私有IP3 } if(ipValue >= A_ADDR_FROM && ipValue <= A_ADDR_TO) { out[0]++; // A类地址 } else if(ipValue >= B_ADDR_FROM && ipValue <= B_ADDR_TO) { out[1]++; // B类地址 } else if(ipValue >= C_ADDR_FROM && ipValue <= C_ADDR_TO) { out[2]++; // C类地址 } else if(ipValue >= D_ADDR_FROM && ipValue <= D_ADDR_TO) { out[3]++; // D类地址 } else if(ipValue >= E_ADDR_FROM && ipValue <= E_ADDR_TO) { out[4]++; // E类地址 } } } } printf("%d %d %d %d %d %d %d\n", out[0],out[1],out[2],out[3],out[4],out[5],out[6]); return 0; }
这题是真的挺难的。。。
总结一下思路:
1、读取一行字符串,把字符串拆分为ip地址字符串和子网掩码字符串;
2、把两个字符串都转化为int 型数组,ip[4],mask[4],比如192.168.0.0转化为{192,168,0,0},当遇到特殊的字符串比如19..0.,对应{19,-1,0,-1}
3、
bool maskIsValid(int* ip);
判断子网掩码是否正确,注意255.255.255.255是不合法的子网掩码,子网掩码转化为32位unsigned int Mask,对Mask取反加一,Mask=~Mask +1;Mask二进制中1的个数是1说明是正确的子网掩码
4、若子网掩码正确,判断Ip地址是否正确;
5、ip地址正确再判断IP地址属于那种类别
// recognize_ip.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; int stringToint(const string& s) { if (s.empty() == true) return -1; int res = 0; for (int i = 0; i < s.size(); ++i) { int cur = s[i] - '0'; res = res * 10 + cur; } return res; } //s1为IP地址类型的字符串 void ipstring_to_arr(int* ip,string& s1) { int start = 0, end = 0; for (int count = 0; end < s1.size(); ++end) { if (s1[end] == '.') { if (count == 2) break; string str = s1.substr(start, end - start); ip[count++] = stringToint(str); start = end + 1; } } string str = s1.substr(start, end - start); ip[2] = stringToint(str); if (end == s1.size()) str = ""; else str = s1.substr(end + 1); ip[3] = stringToint(str); /*for (int i=0;i<4 ;++i) cout << ip[i] << " ";*/ } bool maskIsValid(int* ip) { if (ip[0] == 255 && ip[1] == 255 && ip[2] == 255 && ip[3] == 255) return false; unsigned int Mask = 0; for (int i = 0; i < 4; ++i) { int cur = ip[i]; if (cur 255) return false; Mask = (Mask << 8) + cur; } Mask = ~Mask + 1;//按位取反再加1,正确的子网掩码只剩一个1 if ((Mask & (Mask - 1)) == 0) return true; else return false; } int main() { int result[7] = {0,0,0,0,0,0,0}; //int T = 4; string s; //cin >> s; while (cin >> s) { string s1, s2; int index = 0; bool flag = true; for (; index < s.size(); ++index) { if (s[index] == '~') break; } s1 = s.substr(0, index); s2 = s.substr(index + 1); int ip[4] = { 0 }; int mask[4] = { 0 }; ipstring_to_arr(ip, s1); ipstring_to_arr(mask, s2); /*cout << endl << "mask:" << endl; for (int i : mask) cout << i << " "; cout << endl;*/ bool flag_mask = maskIsValid(mask); if (flag_mask == false) ++result[5]; //判断ip的子网类型 else { for (int i = 0; i < 4; ++i) { if (ip[i] 255) { ++result[5];//错误IP地址 flag = false; break; } } if (flag == true) { if (ip[0] >= 1 && ip[0] <= 126) { ++result[0];//A类地址 if (ip[0] == 10) ++result[6];//私有ip } else if (ip[0] >= 128 && ip[0] <= 191) { if (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) ++result[6];//私有地址 ++result[1];//B类地址 } else if (ip[0] >= 192 && ip[0] <= 223) { if (ip[0] == 192 && ip[1] == 168) ++result[6];//私有地址 ++result[2];//C类地址 } else if (ip[0] >= 224 && ip[0] <= 239) ++result[3];//D类地址 else if (ip[0] >= 240 && ip[0] <= 255) ++result[4];//E类地址 //else //++result[5];//错误IP地址 } } } //std::cout << "输出结果:" << endl; cout<<result[0]<<" "<<result[1]<<" "<<result[2]<<" "<<result[3]<<" "<<result[4]<<" " <<result[5]<<" "<<result[6]<<endl; return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char str[100]; int result[7] = {0}; while(~scanf("%s", str)) { int d1, d2, d3, d4, d11, d22, d33, d44, bin[32] = {0}; memset(bin, 0, 32); if(sscanf(str, "%d.%d.%d.%d~%d.%d.%d.%d", &d11, &d22, &d33, &d44, &d1, &d2, &d3, &d4) == 8) { if(d1 >= 0 && d1 <= 255 && d2 >= 0 && d2 <= 255 && d3 >= 0 && d3 <= 255 && d4 >= 0 && d4 <= 255) { if(d1 == d2 && d2 == d3 && d3 == d4 && (d1 == 0 || d1 == 255)) { //putchar('a'); result[5]++; continue; } else { int i = 7; while(d1) { bin[i] = d1 % 2; i--; d1 /= 2; } i = 15; while(d2) { bin[i] = d2 % 2; i--; d2 /= 2; } i = 23; while(d3) { bin[i] = d3 % 2; i--; d3 /= 2; } i = 31; while(d4) { bin[i] = d4 % 2; i--; d4 /= 2; } int loc0, loc1; for(i = 0; i < 32; i++) if(bin[i] == 0) { loc0 = i; break; } for(i = 31; i >= 0; i--) if(bin[i] == 1) { loc1 = i; break; } /******************************************** for(int x = 0; x < 32; x++) printf("%d ", bin[x]); putchar(10); printf("loc0 = %d, loc1 = %d\n", loc0, loc1); ********************************************/ if(loc0 < loc1) { //putchar('b'); result[5]++; continue; } else//mask is legal { if(d11 >= 0 && d11 <= 255 && d22 >= 0 && d22 <= 255 && d33 >= 0 && d33 <= 255 && d44 >= 0 && d44 <= 255) { if(d11 == 0 || d11 == 127) continue; if(d11 >= 1 && d11 <= 126) result[0]++; else if(d11 >= 128 && d11 <= 191) result[1]++; else if(d11 >= 192 && d11 <= 223) result[2]++; else if(d11 >= 224 && d11 <= 239) result[3]++; else if(d11 >= 240 && d11 <= 255) result[4]++; else { //putchar('c'); result[5]++; continue; } if(d11 == 10) result[6]++; if(d11 == 172 && d22 >= 16 && d22 <= 31) result[6]++; if(d11 == 192 && d22 == 168) result[6]++; } else { //putchar('d'); result[5]++; continue; } } } } else { //putchar('f'); result[5]++; continue; } } else { //putchar('g'); result[5]++; continue; } } for(int j = 0; j < 7; j++) { if(j == 0) printf("%d", result[j]); else printf(" %d", result[j]); } putchar(10); return 0; }注释的全是debug的时候加的,人都傻了
#include <iostream> #include <vector> #include <stack> using namespace std; /* 题目描述 请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。 所有的IP地址划分为 A,B,C,D,E五类 A类地址1.0.0.0~126.255.255.255; B类地址128.0.0.0~191.255.255.255; C类地址192.0.0.0~223.255.255.255; D类地址224.0.0.0~239.255.255.255; E类地址240.0.0.0~255.255.255.255 私网IP范围是: 10.0.0.0~10.255.255.255 172.16.0.0~172.31.255.255 192.168.0.0~192.168.255.255 子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码) 注意二进制下全是1或者全是0均为非法 注意: 1. 类似于【0.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略 2. 私有IP地址和A,B,C,D,E类地址是不冲突的 输入描述: 多行字符串。每行一个IP地址和掩码,用~隔开。 输出描述: 统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。 示例1 输入 10.70.44.68~255.254.255.0 1.0.0.1~255.0.0.0 192.168.0.2~255.255.255.0 19..0.~255.255.255.0 输出 1 0 1 0 0 2 1 */ //将十进制数转换为2进制数string string intto2(long val) { if (val == 0) { return "00000000"; } string str = ""; int i = 0; while (val != 1) { char c = (val % 2 == 0 ? '0' : '1'); str.insert(str.begin(), c); val /= 2; } str.insert(str.begin(), '1'); int n = 8 - str.length() % 8; if (n < 8) { for (int i = 1; i <= n; i++) { str.insert(str.begin(), '0'); } } return str; } //将二进制的string转换为10进制数 long binto10(string str) { long val = 0; for (int i = 0; i < str.length(); i++) { if (str[i] == '1') { long v = 1; for (int j = 1; j <= str.length() - i - 1; j++) { v *= 2; } val += v; } } return val; } //将ip地址转换为2进制数string long ipto10(string ip_str) { vector < int > v_ip; int index = ip_str.find_first_of('.'); while (index != -1) { string part = ip_str.substr(0, index); if (!part.empty()) { v_ip.push_back(stoi(part)); } ip_str = ip_str.substr(index + 1); index = ip_str.find_first_of('.'); } if (!ip_str.empty()) { v_ip.push_back(stoi(ip_str)); } if (v_ip.size() != 4) { return -1; } else { string s = ""; vector < int > ::iterator it; for (it = v_ip.begin(); it != v_ip.end(); it++) { s += intto2( * it); } return binto10(s); } } // bool check_mask(string mask) { vector < int > v_ip; int index = mask.find_first_of('.'); while (index != -1) { string part = mask.substr(0, index); v_ip.push_back(stoi(part)); mask = mask.substr(index + 1); index = mask.find_first_of('.'); } v_ip.push_back(stoi(mask)); if (v_ip.size() != 4) { return false; } else { string binstr = ""; vector < int > ::iterator it; for (it = v_ip.begin(); it != v_ip.end(); it++) { binstr += intto2( * it); } int index = binstr.find_first_of('0'); string tail = binstr.substr(index + 1); if (tail.find('1') != -1) { return false; } else { return true; } } } const long A[] = { ipto10("1.0.0.0"), ipto10("126.255.255.255") }; const long B[] = { ipto10("128.0.0.0"), ipto10("191.255.255.255") }; const long C[] = { ipto10("192.0.0.0"), ipto10("223.255.255.255") }; const long D[] = { ipto10("224.0.0.0"), ipto10("239.255.255.255") }; const long E[] = { ipto10("240.0.0.0"), ipto10("255.255.255.255") }; const long pri1[] = { ipto10("10.0.0.0"), ipto10("10.255.255.255") }; const long pri2[] = { ipto10("172.16.0.0"), ipto10("172.31.255.255") }; const long pri3[] = { ipto10("192.168.0.0"), ipto10("192.168.255.255") }; // C++11 int main() { string str = ""; vector < string > vs; while (getline(cin, str)) { vs.push_back(str); } int nA = 0, nB = 0, nC = 0, nD = 0, nE = 0, nPri = 0, err = 0; for (int i = 0; i < vs.size(); i++) { str = vs[i]; int index = str.find_first_of('~'); string ipstr = str.substr(0, index); string maskstr = str.substr(index + 1); if (!check_mask(maskstr)) { err++; continue; } long ip = ipto10(ipstr); if (ip == -1) { err++; } else { if (A[0] < ip && ip < A[1]) { nA++; } else if (B[0] < ip && ip < B[1]) { nB++; } else if (C[0] < ip && ip < C[1]) { nC++; } else if (D[0] < ip && ip < D[1]) { nD++; } else if (E[0] < ip && ip < E[1]) { nE++; } if ((pri1[0] < ip && ip < pri1[1]) || (pri2[0] < ip && ip < pri2[1]) || (pri3[0] < ip && ip < pri3[1])) { nPri++; } } } cout << nA << ' ' << nB << ' ' << nC << ' ' << nD << ' ' << nE << ' ' << err << ' ' << nPri << endl; return 0; }
//1 255.255.255.255,0.0.0.0 为非法子网掩码 //2 ip地址是不用考虑大于255的情况,以及127.x.x.x,0.0.0.0 这些忽视数据而不是算错 //2 当子网掩码错误时,不在判断ip是否有效,错误直接加一, 进行下次循环 //3 当一个ip属于ABCDE类中的一个时候,也属于私有ip时,私有ip和他属于的分类都应该加一 #include <stdio.h> (737)#include <stdlib.h> #include <string.h> int IsMask(char *str) { int i = 0,mask=0,n,temp; temp = atoi(str+i); //提取掩码的第一部分,保存在高24位 mask |= (temp<<24); while(str[i++]!='.'); temp = atoi(str + i); //提取掩码的第二部分,保存在高16位 mask |= (temp<<16); while(str[i++]!='.'); temp = atoi(str + i); //提取掩码的第三部分,保存在高8位 mask |= (temp<<8); while(str[i++]!='.'); //提取掩码的第四部分, 保存在低8位 temp = atoi(str + i); mask |= (temp<<0); if(mask == 0xffffffff || mask == 0) //如果掩码全为0,或者全为1,返回0 ,标示非法 return 0; for(i=31; i>1; i--) //从最高位开始找,若发现有01这种情况即可判定非法 { if(((mask >> i) & 0x1) ==0 && ((mask>>(i-1)) & 0x1) ==1) return 0; } return 1; } int main() { int i,n,cnt,num[4]; char temp[32]={0}; //每次输入的数据,放在temp数组临时保存 int class[7]={0}; //用于统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数 while(scanf("%s",temp) != EOF) { if(!IsMask(strchr(temp,'~')+1)) //如果掩码错误,直接错误+1,进行下次的判断 { class[5]++; continue; } for(i=0,cnt=0; temp[i] != '~';i++) //循环查找 { n = atoi(temp+i); if(n == 0 && temp[i] == '0' && cnt == 0) //ip为0.x.x.x的直接忽略 break; if(n == 0 && temp[i] == '.') //ip为.x..x等情况说明输入错误 { class[5]++; break; } num[cnt++] = n; if(cnt == 4) //当提取到了ip的4部分数据才判断是哪一类 { if(num[0] >= 1 && num[0] <= 126 ) //A类地址 { class[0]++; if(num[0] == 10 ) //私网IP class[6]++; } else if(num[0] >= 128 && num[0] <= 191) //B类地址 { class[1]++; if(num[0] == 172 && num[1] >= 16 && num[1] <= 31)//私网IP class[6]++; } else if(num[0] >= 192 && num[0] <= 223) //C类地址 { class[2]++; if(num[0] == 192 && num[1] == 168 ) //私网IP class[6]++; } else if(num[0] >= 224 && num[0] <= 239) //D类地址 class[3]++; else if(num[0] >= 240 && num[0] <= 255) //E类地址 class[4]++; } while(temp[i] != '.' && temp[i] != '~') //寻找到下一个'.' i++; if(temp[i] == '~') break; //若发现'~',说名已经处理完 } } for(i=0;i<7;i++) //输出显示,注意输出的最后一位不能有空格 if(i<6) printf("%d ",class[i]); else printf("%d",class[i]); return 0; }
这里的思路是一边读入一边统计,每次换行都处理一次,附加代码以便参考
#include (849)#include #include (849)#define ADDR_A_START 0x01000000 #define ADDR_A_END 0X7EFFFFFF (1210)#define ADDR_B_START 0x80000000 #define ADDR_B_END 0XBFFFFFFF (1211)#define ADDR_C_START 0xC0000000 #define ADDR_C_END 0XDFFFFFFF (1212)#define ADDR_D_START 0XE0000000 #define ADDR_D_END 0XEFFFFFFF (1213)#define ADDR_E_START 0XF0000000 #define ADDR_E_END 0XFFFFFFFF (1214)#define ADDR_S_START_1 0X0A000000 #define ADDR_S_END_1 0X0AFFFFFF (1215)#define ADDR_S_START_2 0XAC100000 #define ADDR_S_END_2 0XAC1FFFFF (1216)#define ADDR_S_START_3 0XC0A80000 #define ADDR_S_END_3 0XC0A8FFFF unsigned int getHex(unsigned int ip[8],int isIp){ unsigned int result=0; if(isIp){ for(int i=0;i<4;i++){ result<<=8; result+=ip[i]; } }else{ for(int i=4;i<8;i++){ result<<=8; result+=ip[i]; } } return result; } bool checkMark(unsigned int code){ int counterR=0; while (!(code&0x01))//找到第一个1的位置 { code>>=1; counterR++; } if(counterR==0) return false; counterR=32-counterR; while(counterR--) { code>>=1; if(!(code&0x01)){ break; } } if(counterR!=0){ return false; } else{ return true; } } int main(){ int ips[1000][8]={0}; char in=0,lastIn=0; int counter=0,position=0,num=0; int wrongSign=0; int A=0,B=0,C=0,D=0,E=0,W=0,S=0; unsigned int markCode=0,tempIP=0; while((in=getchar())!=EOF){ if('.'==in||'~'==in){//一个数字输入完毕 if(lastIn>'9'||lastIn<'0'){ wrongSign=1; } ips[counter][position]=num; position++; num=0; lastIn=in; }else if('\n'==in){//一行输入完毕 ips[counter][position]=num; if(lastIn>'9'||lastIn<'0'){ wrongSign=1; } markCode=getHex(ips[counter],0); unsigned int temp1=markCode; //检查掩码 if(!checkMark(markCode)) { wrongSign=1; } if(wrongSign){ memset(ips[counter],0,4*sizeof(unsigned int)); W++; wrongSign=0; } else{ // printf("Mask->%d.%d.%d.%d\n",ips[counter][4],ips[counter][5],ips[counter][6],ips[counter][7]); //分析地址 tempIP=getHex(ips[counter],1); if(tempIP>=ADDR_A_START&&tempIP<=ADDR_A_END) A++; if(tempIP>=ADDR_B_START&&tempIP<=ADDR_B_END) B++; if(tempIP>=ADDR_C_START&&tempIP<=ADDR_C_END) C++; if(tempIP>=ADDR_D_START&&tempIP<=ADDR_D_END) D++; if(tempIP>=ADDR_E_START&&tempIP<=ADDR_E_END) E++; if(tempIP>=ADDR_S_START_1&&tempIP<=ADDR_S_END_1) S++; if(tempIP>=ADDR_S_START_2&&tempIP<=ADDR_S_END_2) S++; if(tempIP>=ADDR_S_START_3&&tempIP<=ADDR_S_END_3) S++; //end counter++; } num=0; position=0; lastIn=in; continue; } else{ num=num*10+(in-'0'); lastIn=in; } } /* for(int i=0;i<counter;i++){ printf("Valid:%d.%d.%d.%d~%d.%d.%d.%d\n",ips[i][0],ips[i][1],ips[i][2],ips[i][3],ips[i][4],ips[i][5],ips[i][6],ips[i][7]); } */ //开始处理地址 printf("%d %d %d %d %d %d %d\n",A,B,C,D,E,W,S); return 0; }
#include<stdio.h> #include<string.h> int main() { int ip_num[8],result[7]={},mask_bin[32],flag1,flag2,flag3,i,j,k,cnt_0,cnt_1; while(scanf("%d.%d.%d.%d~%d.%d.%d.%d", &ip_num[0], &ip_num[1], &ip_num[2], &ip_num[3], &ip_num[4], &ip_num[5], &ip_num[6], &ip_num[7]) != EOF) { flag1 = 0; flag2 = 0; flag3 = 0; cnt_0 = 0; cnt_1 = 0; j = 0; for (i = 0; i < 8; i++) { if (ip_num[i] < 0 || ip_num[i] > 255) { result[5]++; flag1 = 1; break; } } if(flag1 == 0) { for (i = 4; i < 8;i++) { k = 128; if(ip_num[i] == 0) { cnt_0++; } else if(ip_num[i] == 255) { cnt_1++; } //写的十进制转二进制方法,可模块化 while(j<=(8*(i-3)-1)) { if(ip_num[i] / k) { mask_bin[j] = 1; ip_num[i] = ip_num[i] - k; } else { mask_bin[j] = 0; } k /= 2; j++; } } if(cnt_0 == 4 || cnt_1 == 4) { result[5]++; flag2 = 1; } if(flag2==0) { for (i = 0; i < 31;i++) { if(mask_bin[i+1]>mask_bin[i]) { result[5]++; flag3 = 1; break; } } } } if(flag1 == 0 && flag2 == 0 && flag3 == 0) { if(ip_num[0]>=1&&ip_num[0]<=126) result[0]++; else if(ip_num[0]>=128&&ip_num[0]<=191) result[1]++; else if(ip_num[0]>=192&&ip_num[0]<=223) result[2]++; else if(ip_num[0]>=224&&ip_num[0]<=239) result[3]++; else if(ip_num[0]>=240&&ip_num[0]<=255) result[4]++; if(ip_num[0]==10 || (ip_num[0]==172&&ip_num[1]>=16&&ip_num[1]<=31) || (ip_num[0]==192 && ip_num[1]==168)) { result[6]++; } } } printf("%d %d %d %d %d %d %d", result[0], result[1], result[2], result[3], result[4], result[5], result[6]); return 0; }