识别有效的IP地址和掩码并进行分类统计

在牛客网上,刷了这一题,并用牛客网提供的OJ。总结了一些,编程中遇到的问题。

题目描述

请解析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

输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:

统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。

输入例子:
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

本题的关键在于掩码的检查:
1、255.255.255.255,0.0.0.0不合法;
2、255.63.255.0,这种形式的,63是低位全1,后台代码检测时应该把高位去掉,所以这个是合法,
3、同理255.255.255.32,32是高位有0,低位也有0,所以合法,但是255.255.255.31,尽管高位有0被去掉而低位全1,因为高位0被去掉以后,剩下的就是全1了,这种情况就被当成第1种情况处理了,所以这个不合法。
4、注意255.0.0.32,不要在编程的时候把中间两个省略掉,否则就会变成合法的了。
5、 A类地址1.0.0.0~126.255.255.255; 例如:0.98.251.80,不属于A类的范围,但是也不是错误的;大于255.255.255.255的IP不属于任一类,但是格式上没有错误。
 
这个是根据的我测试结果猜测的,可能有其他的原因,但是按照这个规律,用C语言来做是可以AC的,所以上面结论差不多正确。
  1 #include <iostream>
  2 #include <stdlib.h>
  3 #include <string>
  4 #include <math.h>
  5 
  6 using namespace std;
  7 
  8 int A_count = 0;
  9 int B_count = 0;
 10 int C_count = 0;
 11 int D_count = 0;
 12 int E_count = 0;
 13 int error_count = 0;
 14 int private_IP_count = 0;
 15 
 16 int IP_tmp[4] = { 0, 0, 0, 0 };
 17 
 18 int IP_error(string str)
 19 {
 20     int pos = 0;
 21     string temp[4];
 22     for (int i = 0; i < 4; i++)
 23     {
 24         IP_tmp[i] = 0;
 25     }
 26     
 27 
 28     for (int i = 0; i < 3; i++)
 29     {
 30         pos = str.find(".");
 31         temp[i] = str.substr(0, pos);
 32         str = str.substr(pos + 1, str.size());
 33     }
 34     if (str.find(".") != str.npos) //点分错误
 35     {
 36         error_count++;
 37         return 1;
 38     }
 39     temp[3] = str;
 40 
 41     for (int i = 0; i < 4; i++)    //每段的位数错误
 42     {
 43         if (!(temp[i].size() >= 1 && temp[i].size() <= 3))
 44         {
 45             error_count++;
 46             return 1;
 47         }
 48     }
 49     for (int j = 0; j < 4; j++)
 50     {
 51         for (int i = temp[j].size() - 1; i >= 0; i--)    //是不是0-9之间
 52         {
 53             if (!(temp[j][i] >= '0' && temp[j][i] <= '9'))
 54             {
 55                 error_count++;
 56                 return 1;
 57             }
 58             else
 59             {
 60                 IP_tmp[j] += (temp[j][i] - '0')*pow(10, temp[j].size() - 1 - i);
 61             }
 62         }
 63     }
 64     return 0;
 65 }
 66 int IP_area(int Array0,int Array1)
 67 {
 68     if (Array0 >= 1 && Array0 <= 126)
 69     {
 70         A_count++;
 71         if (Array0 == 10)
 72         {
 73             private_IP_count++;
 74         }
 75     }
 76     else if (Array0 == 127 && Array1 >= 16 && Array1 <= 31)
 77     {
 78         private_IP_count++;
 79     }
 80     else if (Array0 >= 128 && Array0 <= 191)
 81     {
 82         B_count++;
 83     }
 84     else if (Array0 >= 192 && Array0 <= 223)
 85     {
 86         C_count++;
 87         if (Array0 == 192 && Array1 == 168)
 88         {
 89             private_IP_count++;
 90         }
 91     }
 92     else if (Array0 >= 224 && Array0 <= 239)
 93     {
 94         D_count++;
 95     }
 96     else if (Array0 >= 240 && Array0 <= 255)
 97     {
 98         E_count++;
 99     }
100     else
101     {
102         //error_count++;
103         return 0;
104     }
105     return 0;
106 }
107 int Mark_error(string str)
108 {
109     int pos = 0;
110     string temp[4];
111     int tmp[4] = { 0 };
112 
113     for (int i = 0; i < 3; i++)
114     {
115         pos = str.find(".");
116         temp[i] = str.substr(0, pos);
117         str = str.substr(pos + 1, str.size());
118     }
119     if (str.find(".") != str.npos) //点分错误
120     {
121         error_count++;
122         return 1;
123     }
124     temp[3] = str;
125 
126     for (int i = 0; i < 4; i++)    //每段的位数错误
127     {
128         if (!(temp[i].size() >= 1 && temp[i].size() <= 3))
129         {
130             error_count++;
131             return 1;
132         }
133     }
134     for (int j = 0; j < 4; j++)
135     {
136         for (int i = temp[j].size() - 1; i >= 0; i--)    //是不是0-9之间
137         {
138             if (!(temp[j][i] >= '0' && temp[j][i] <= '9'))
139             {
140                 error_count++;
141                 return 1;
142             }
143             else
144             {
145                 tmp[j] += (temp[j][i] - '0')*pow(10, temp[j].size() - 1 - i);
146             }
147         }
148     }
149     char flag = 0;
150     string b;
151     for (int j = 0; j < 4; j++)
152     {
153         for (int i = 7; i >= 0; i--)
154         {
155             if (((tmp[j] >> i) & 1) == 1)
156             {
157                 flag = 1;
158                 b.push_back('1');
159             }
160             if (((tmp[j] >> i) & 1) == 0 && flag == 1)
161             {
162                 b.push_back('0');
163             }
164         }
165         if (flag == 0)
166         {
167             b.push_back('0');
168         }
169         else
170         {
171             flag = 0;
172         }
173         
174     }
175     if (b.find('0') != b.npos && b.find('1') != b.npos)
176     {
177         if (b.find_first_of('0') < b.find_last_of('1'))
178         {
179             error_count++;
180             return 1;
181         }
182     }
183     else
184     {
185         error_count++;
186         return 1;
187     }
188     return 0;
189 }
190 int main(void)
191 {
192     string str;
193 
194 
195     while (getline(cin, str))
196     {
197         string str1, str2;
198         int pos;
199         pos = str.find("~");
200         str1 = str.substr(0, pos);
201         str2 = str.substr(pos + 1, str.size());
202 
203         if (IP_error(str1) == 0)
204         {
205             if (Mark_error(str2) == 0)
206             {
207                 IP_area(IP_tmp[0],IP_tmp[1]);
208             }
209         }
210         //cout << A_count << ' ' << B_count << ' ' << C_count << ' ' << D_count << ' ' << E_count << ' ' << error_count << ' ' << private_IP_count << endl;
211 
212     }
213     cout << A_count << ' ' << B_count << ' ' << C_count << ' ' << D_count << ' ' << E_count << ' ' << error_count << ' ' << private_IP_count << endl;
214 
215     return 0;
216 }

 

posted @ 2016-05-28 16:34  hhboboy  阅读(1635)  评论(0编辑  收藏  举报