之前遇到过一道这样的面试题,编写一个函数,功能是判断一个IP地址的合法性,传入参数为字符串,而且需要匹配十六进制的IP地址(例B2.168.2.13是合法的,因为转换成十进制后等于112.168.2.13)。当时我就想到了牛客上的一道题目:输入一个ip地址,判断是否合法。然后就想到了当时看到的答案,代码如下:
#include <stdio.h>
int main()
{
int a,b,c,d;
while(scanf("%d.%d.%d.%d",&a,&b,&c,&d)!=EOF)
{
if((a>=0&&a<=255)&&(b>=0&&b<=255)&&(c>=0&&c<=255)&&(d>=0&&d<=255))
printf("Yes!\n");
else
printf("No!\n");
}
return 0;
}
当时我就懵了,怎么不按套路出牌呢。显然,这答案有点投巧,仅仅是键盘输入,完全不能移植过来啊。所以还是得自己手撕,代码可能有不完善的地方, 如果看出来了还望大家能指出。解题方法有很多种,下面就列出我想到的,使用C语言实现,代码仅供参考。
#include <stdio.h>
#include <string.h>
int IpJudge(const char * str)
{
char a[16]; //存放字符串
char *b[4]; //存放分段后的字符串
int c[4]; //存放转换成int类型后的数据
int i,j;
int len;
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
memcpy(a,str,sizeof(a));
len=strlen(a);
if(len<7||len>15) //IP地址最短为7位,最长为15位
{
printf("NO\n");
return -1;
}
b[0]=strtok(a,".");
for(i=1;i<4;i++)
{
b[i]=strtok(NULL,".");
if(b[i]==NULL)
{
printf("NO\n");
return -1;
}
}
if(strtok(NULL,".")!=NULL)
{
printf("NO\n");
return -1;
}
for(i=0;i<4;i++)
{
len=strlen(b[i]);
if(len<1||len>3) //每段数据最长为3,最短为1
{
printf("NO\n");
return -1;
}
else if(len==1||len==2)
{
for(j=0;j<len;j++)
{
if(b[i][j]>='0'&&b[i][j]<='9')
{
c[i]*=10;
c[i]+=(b[i][j]-'0');
}
else if((b[i][j]>='a'&&b[i][j]<='f')||(b[i][j]>='A'&&b[i][j]<='F'))
{
if(c[i]!=0)
{
c[i]*=100;
c[i]+=(b[i][j]-'a')>=0?(b[i][j]-'a'+10):(b[i][j]-'A'+10);
}
else
{
c[i]+=(b[i][j]-'a')>=0?(b[i][j]-'a'+10):(b[i][j]-'A'+10);
}
}
else
{
printf("NO\n");
return -1;
}
}
}
else if(len==3)
{
for(j=0;j<len;j++)
{
if(b[i][j]>='0'&&b[i][j]<='9')
{
c[i]*=10;
c[i]+=(b[i][j]-'0');
}
else
{
printf("NO\n");
return -1;
}
}
}
}
for(i=0;i<4;i++)
{
if(c[i]<0||c[i]>255)
{
printf("NO\n");
return -1;
}
}
printf("YES\n");
return 0;
}
int main()
{
char test[6][15]={"192.168.1.1",
"256.125.2.56",
"B2.165.16.3",
"c3.d2.f4.1A",
"1234.23.34.1",
"192.168.1.2.4"};
int i;
for(i=0;i<6;i++)
{
IpJudge(test[i]);
}
return 0;
}
输出:
YES
NO
YES
YES
NO
NO