题解 | #识别有效的IP地址和掩码并进行分类统计#
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
注意问题:
1.掩码判断:利用数组将可能出现的数字列出来,以此判断。{0,128,192,224,240,248,252,254,255},不是这些数肯定有误;
2.掩码全为255或0记为有误,易忽略该情况;
3.私人ip地址值注意审题;
4.无效ip地址值的理解,只要以0或127开头直接记为无效,不与其他情况讨论;
5.此题主要是考察逻辑性,算法上无难度。
#include <stdio.h>
#include <string.h>
int trans_num(char str[],int a,int b)//str字符串a到b-1对应的数字
{
int num=0,i;
for(i=a;i<b;i++)
if('0'<=str[i]&&str[i]<='9') num=num*10+str[i]-'0';
else return -200;
return num;
}
int jud_yanma(int yanma[])//判断是否符合掩码正常格式,符合返回0,否则返回1
{
int i,j,num;
for(i=0;i<4;i++)
if(yanma[i]!=255) break;
for(i=i+1;i<4;i++)
if(yanma[i]!=0) return 1;
return 0;
}
int all_255(int yanma[])
{
int i,jud=1;
for(i=0;i<4;i++)
if(yanma[i]!=255)
{
jud=0;
break;
}
return jud;
}
int all_0(int yanma[])
{
int i,jud=1;
for(i=0;i<4;i++)
if(yanma[i]!=0)
{
jud=0;
break;
}
return jud;
}
int main()
{
int A=0,B=0,C=0,D=0,E=0,err=0,pri=0;
char str[200];
int length,i,j;
int note[7],num[4],yanma[4];//六个'.'和一个'~'的标号,四个ip地址数字
int jud[9]={0,128,192,224,240,248,252,254,255};
while(gets(str)!=NULL)
{
int k=0;
length=strlen(str);
for(i=0;i<length;i++)
if(str[i]=='.'||str[i]=='~') note[k++]=i;
num[0]=trans_num(str, 0, note[0]);
num[1]=trans_num(str, note[0]+1, note[1]);
num[2]=trans_num(str, note[1]+1, note[2]);
num[3]=trans_num(str, note[2]+1, note[3]);
/*无效ip地址*/
if(num[0]==0||num[0]==127) continue;
/*错误ip地址*/
if((note[1]==note[0]+1)||(note[2]==note[1]+1))//无数字,ip地址有误
{
err++;
continue;
}
for(i=0;i<4;i++) //不是数字,ip地址有误
if(num[i]<0)
{
err++;
continue;
}
/*掩码有误*/
int jud_err[4];
int r;
memset(jud_err, 0, 4);
yanma[0]=trans_num(str, note[3]+1, note[4]);
yanma[1]=trans_num(str, note[4]+1, note[5]);
yanma[2]=trans_num(str, note[5]+1, note[6]);
yanma[3]=trans_num(str, note[6]+1, length);
for(i=0;i<4;i++)
{
r=0;
for(j=0;j<9;j++)
if(yanma[i]==jud[j])
{
r=1;
break;
}
jud_err[i]=r;
}
r=0;
r=all_0(yanma);
r=all_255(yanma);
for(i=0;i<4;i++)
if(jud_err[i]==0)
{
r=1;
break;
}
if(jud_yanma(yanma)) r=1;
if(r==1)
{
err++;
continue;
}
/*正确ip地址*/
if (1<=num[0]&&num[0]<=126) A++;
else if (128<=num[0]&&num[0]<=191) B++;
else if (192<=num[0]&&num[0]<=223) C++;
else if (224<=num[0]&&num[0]<=239) D++;
else if (240<=num[0]&&num[0]<=255) E++;
/*私人ip地址*/
if(num[0]==10) pri++;
if(num[0]==172)
if('16'<=num[1]&&num[1]<='31') pri++;
if(num[0]==198&&num[1]==168) pri++;
}
printf("%d %d %d %d %d %d %d\n",A,B,C,D,E,err,pri);
return 0;
}

