题目
描述
请解析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地址和掩码,已~隔开。如:
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
输出
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开,根据上面的IP,可以得到:
1.0.0.1~255.0.0.0 —-A类
192.168.0.2~255.255.255.0 —-C类,私有
10.70.44.68~255.254.255.0—-错误的掩码
19..0.~255.255.255.0—–错误的IP
可以得到统计数据如下:
1 0 1 0 0 2 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
思路
字符串的截取
while(i<ip1.size())
{
int tmp=i;
while(isdigit(ip1[tmp]))
tmp++;
str1[k]=ip1.substr(i,tmp-i);
k++;
i=tmp+1;
}
string Chang(string str) //转换为二进制
{
int num=atoi(str.c_str());
string tmp;
char tmp1[10]={0};
itoa(num,tmp1,2);
tmp=string(tmp1);
if (tmp.size()<8)
{
string tmp2(8-tmp.size(),'0');//创建临时字符串填充到前面
str=tmp2+tmp;
}
else
str=tmp;
return str;
}
代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
static int result[7]= {0}; //保存最后结果的数组
string Chang(string str) //转换为二进制
{
int num=atoi(str.c_str());
string tmp;
char tmp1[10]= {0};
itoa(num,tmp1,2);
tmp=string(tmp1);
if (tmp.size()<8)
{
string tmp2(8-tmp.size(),'0');//创建临时字符串填充到前面
str=tmp2+tmp;
}
else
str=tmp;
return str;
}
void checkNetSegment(string mask,string ip1)
{
int count1=0;//掩码的点个数(不连续的点等于3个)
int count2=0;//ip1的点个数
int count4=0;//掩码的点个数(所有的点等于3个)
int count5=0;//ip1的点个数
string str1[4],str3[4];
for(int i=0; i<mask.size(); i++)
{
if(mask[i]=='.' && mask[i+1]!='.')
{
count1++;//掩码的点个数(不连续的点等于3个)
}
if(mask[i]=='.')
count4++;//掩码的点个数(所有的点等于3个)
}
for(int i=0; i<ip1.size(); i++)
{
if(ip1[i]=='.' && ip1[i+1]!='.')
{
count2++;//ip1的点个数(不连续的点等于3个)
}
if(ip1[i]=='.')
{
count5++;//ip1的点个数(所有的点等于3个)
}
}
//利用对点的个数判断是否格式正确
if(count1==count2&&count1==3
&& count4==count5&&count4==3) //如果格式正确
{
int i=0; //ip1先分解为4段
int flag1=0;
int k=0;
while(i<ip1.size())
{
int tmp=i;
while(isdigit(ip1[tmp]))
tmp++;
str1[k]=ip1.substr(i,tmp-i);
k++;
i=tmp+1;
}
i=0; //掩码分为4段
int flag3=0,flagmk=0;
k=0;
string test;
while(i<mask.size())
{
int tmp=i;
while(isdigit(mask[tmp]))
tmp++;
str3[k]=mask.substr(i,tmp-i);
k++;
i=tmp+1;
}
for(int i=0; i<4; i++)
{
//判断每一段的值是否在0-255之间
if(atoi(str1[i].c_str())<256 &&atoi(str1[i].c_str())>=0)
{
flag1++;//IP
}
}
for(int i=0; i<4; i++)
{
if(atoi(str3[i].c_str())<256 &&atoi(str3[i].c_str())>=0)
{
flag3++;//MASK
}
}
for (int i=0; i<4; i++) //判掩码是不是1在0前面
{
string temp=Chang(str3[i]);
test+=temp;
}
for (int j=1; j<32-1; j++)
{
if (test[j-1]>test[j] && test[j]<test[j+1])
{
flagmk=1;
break;
}
}
if(flag1==flag3 &&flag3==4 &&flagmk==0) //格式正确
{
if (str1[0]>="1" &&str1[0]<="126" )
{
result[0]++;
}
else if (str1[0]>="128" &&str1[0]<="191")
{
result[1]++;
}
else if (str1[0]>="192"&&str1[0]<="223")
{
result[2]++;
}
else if (str1[0]>="224"&&str1[0]<="239")
{
result[3]++;
}
else if (str1[0]>="240"&&str1[0]<="255")
{
result[4]++;
}
else if (str1[0]=="127")
{
result[5]++;
}
if (str1[0]=="10"|| //私有IP
(str1[0]=="172"&&str1[1]>="16"&&str1[1]<="31")||
(str1[0]=="192"&&str1[1]=="168"))
{
result[6]++;
}
}
else
{
result[5]++;
}
}
else
{
result[5]++; //格式不正确
}
}
int main()
{
string s1,ms,ip;
while (getline(cin,s1))
{
//截取字符串
int position=s1.find("~",0);
ip=s1.substr(0,position);
ms=s1.substr(position+1,s1.size()-1);
checkNetSegment(ms,ip);
}
for (int i=0; i<7; i++)
{
cout<<result[i];
if (i==6)
{
cout<<endl;
}
else
{
cout<<" ";
}
}
return 0;
}
另外:网上搜罗来的代码
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
bool checkip(vector<int> num)
{
for (int i = 0; i < 4; i++)
{
if (num[i] < 0 || num[i] > 255)
{
return false;
}
}
return true;
}
bool checkmark(vector<int> num)
{
int sum = num[0] << 24 | num[1] << 16 | num[2] << 8 | num[3];
bool b = false;
for (int i = 0; i < 32; i++)
{
if ((sum & 1 << i) == 0)
{
if (b == true)
{
return false;
}
}
else
{
b = true;
}
}
return true;
}
int str2num(string str)
{
int res = 0;
for (int i = 0; i < str.size(); i++)
{
res = res * 10 + str[i] - '0';
}
return res;
}
vector<int> seperate(string str)
{
vector<int> ss;
int i = 0;
int j;
string temp;
while ((j = str.find('.', i)) != string::npos)
{
temp = str.substr(i, j - i);
if (temp.size() != 0)
{
ss.push_back(str2num(temp));
}
else
{
ss.push_back(-1);
}
i = j + 1;
}
temp = str.substr(i);
if (temp.size() != 0)
{
ss.push_back(str2num(temp));
}
else
{
ss.push_back(-1);
}
return ss;
}
int main()
{
string str;
int cnt[7] = {0};
while (getline(cin, str))
{
if (str.size() == 0)
{
break;
}
int i = 0;
int j;
j = str.find('~');
string strIp = str.substr(0, j);
string strMark = str.substr(j + 1);
vector<int> ip = seperate(strIp);
vector<int> mark = seperate(strMark);
if (checkip(ip) && checkmark(mark))
{
if (ip[0] >= 1 && ip[0] <= 126)
{
cnt[0]++;
}
else if (ip[0] >= 128 && ip[0] <= 191)
{
cnt[1]++;
}
else if (ip[0] >= 192 && ip[0] <= 223)
{
cnt[2]++;
}
else if (ip[0] >= 224 && ip[0] <= 239)
{
cnt[3]++;
}
else
{
cnt[4]++;
}
if ((ip[0] == 10) || (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31)
|| (ip[0] == 192 && ip[1] == 168))
{
cnt[6]++;
}
}
else
{
cnt[5]++;
}
}
for (int i = 0; i < 7; i++)
{
cout<<cnt[i]<<" ";
}
}