每日一题 C++版(分类有效的IP地址和掩码)
编程是很多偏计算机、人工智能领域必须掌握的一项技能,此编程能力在学习和工作中起着重要的作用。因此小白决定开辟一个新的板块“每日一题”,通过每天一道编程题目来强化和锻炼自己的编程能力(最起码不会忘记编程)
特别说明:编程题来自“牛客网”和“领扣”以及热心小伙伴的题目。由于小白有时想锻炼某一类编程方法,所以提供的代码不一定是最优解,但是本文提供的编程代码均为通过测试代码。
分类有效的IP地址和掩码
题目描述
请解析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就是一个非法的掩码)
本题暂时默认以0开头的IP地址是合法的,比如0.1.1.2,是合法地址
输入描述:
多行字符串。每行一个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
解析
这个题思路比较清晰,主要实现三个功能,这里单独使用三个函数来实现这个功能,分别是:
stringtoint():将string转换成int的函数,由于int<255所以不用考虑转换的结果是否会溢出。
toint()函数:将一个完整的ip地址或者mask转换对应的字符串转换成int放入vector中,这样可以通过判断vector里面的4个数值的范围进行判断即可。简化了操作。
masklivalid():函数功能是判断mask(子网掩码)是否有效, 如果第一个是255,则判断第二个是不是255,若第二个不是255,则第三个和第四个必须是0,(见子网掩码的规则,前面为1,后面为0),同时第二个必须是254,252,248,240,224,192,128,0;至于原因,将他们转换成二进制,前面为连续的1,后面为连续的0,符合要求。若第二个为255,则第三个以此类推。如果第一个不是255,则同理,只能是254,252,248,240,224,192,128(注意不能为0),因为子网掩码mask可以以0开头,但不是有效的掩码。
理解完这几个函数(其实很好理解对吧?)
我们就可以以很清晰的思路进行编写程序:
1、先判断子网掩码mask是否有效,无效的话,直接无效数目+1;
2、若有效;再分别判断属于哪一类IP地址。
但是小白当时得出的结果是60%通过,A类地址少一个。这是因为私有IP地址和A,B,C,D,E类地址是不冲突的,什么意思呢?就是A,B,C,D,E类地址也可以是私有地址,只要他们符合私有地址的规则。所以不能用if...,else if...,而应该用if... if...(或者在各自类中再进行判断是否既属于该类又属于私有地址的情况)。
代码
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;
int stringtoint(string str){
stringstream ss;
ss<<str;
int x;
ss>>x;
return x;
}
vector<int> toint(string str){
vector<int> res;
string temp;
int ele;
for(int i=0;i<str.length();i++){
if(str[i]!='.'){
temp.push_back(str[i]);
}
else{
ele=stringtoint(temp);
temp.clear();
res.push_back(ele);
}
}
ele=stringtoint(temp);
res.push_back(ele);
return res;
}
bool maskisvalid(vector<int> res){
if(res.size()!=4)
return false;
if(res[0]==255){
if(res[1]==255){
if(res[2]==255){
if(res[3]==254||res[3]==252||res[3]==248||res[3]==240||res[3]==224||res[3]==192||res[3]==128||res[3]==0){
return true;
}
else{
return false;
}
}
else{
if(res[2]==254||res[2]==252||res[2]==248||res[2]==240||res[2]==224||res[2]==192||res[2]==128||res[2]==0){
if(res[3]==0){
return true;
}
else{
return false;
}
}
}
}
else{
if(res[1]==254||res[1]==252||res[1]==248||res[1]==240||res[1]==224||res[1]==192||res[1]==128||res[1]==0){
if(res[3]==0&&res[2]==0){
return true;
}
else{
return false;
}
}
}
}
else{
if(res[0]==254||res[0]==252||res[0]==248||res[0]==240||res[0]==224||res[0]==192||res[0]==128){
if(res[3]==0&&res[2]==0&&res[1]==0){
return true;
}
}
else{
return false;
}
}
return false;
}
int main(){
string str;
int* res=new int[7];
for(int j=0;j<7;j++)
res[j]=0;
while(cin>>str){
string ipstring;
string maskstring;
vector<int> ip,mask;
int i=0;
for(;str[i]!='~';i++){
ipstring.push_back(str[i]);
}
i++;
for(;i<str.length();i++){
maskstring.push_back(str[i]);
}
ip=toint(ipstring);
mask=toint(maskstring);
if(maskisvalid(mask)){
if(ip[1]>=0&&ip[1]<=255&&ip[2]>=0&&ip[2]<=255&&ip[3]>=0&&ip[3]<=255){
if(ip[0]>=1&&ip[0]<=126){
res[0]++;
if(ip[0]==10)
res[6]++;
}
else if(ip[0]>=128&&ip[0]<=191){
res[1]++;
if(ip[0] == 172 && ip[1] >= 16 && ip[1] <= 32)
res[6]++;
}
else if(ip[0]>=192&&ip[0]<=223){
res[2]++;
if(ip[0] == 192 && ip[1] == 168)
res[6]++;
}
else if(ip[0]>=224&&ip[0]<=239){
res[3]++;
}
else if(ip[0]>=240&&ip[0]<=255){
res[4]++;
}
}
}
else{
res[5]++;
}
}
cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<" "<<res[3]<<" "<<res[4]<<" "<<res[5]<<" "<<res[6]<<endl;
return 0;
}