如题,ipv4地址的“点分十进制”的格式是:1.2.3.4,十进制的数字必须在[0, 255]之间。先po我自己的代码,再对比大师们的代码。
思路
首先要照惯例立一个flag:这是一个十分简单的问题。
然后,这个问题确实很简单。不合法不外乎这几个条件:
1. 含有非法字符(即除了数字和’.’意外的字符);
2. 没有四部分;
3. 每部分里的数字不在[0, 255]上,由于没有负数(因为负号包含第一种情况中),所以就是每部分里的数字大于255。
所以我们线性扫一遍,排除掉非法字符,再记录’.’的个数,以及维护每部分的数字(这个有个小技巧,看代码),就可以了!
bool isIPV4Address(const string& address) {
int len = address.size();
// 这个判断是一个小优化,去掉很大的字符串这种情况
if (len < 7 || len > 15)
return false;
// 注意number的值是如何维护的!
int countOfDot = 0, number = 0;
for (int i = 0; i < len; ++i) {
if (address[i] == '.') {
if (number > 255)
return false;
number = 0;
++countOfDot;
} else if (address[i] < '0' || address[i] > '9') {
return false;
} else {
number *= 10;
number += address[i] - '0';
}
}
return countOfDot == 3;
}
整体的代码如下:
// 测评地址:kAri OJ
#include <iostream>
#include <string>
using namespace std;
bool isIPV4Address(const string& address) {
int len = address.size();
if (len < 7 || len > 15)
return false;
int countOfDot = 0, number = 0;
for (int i = 0; i < len; ++i) {
if (address[i] == '.') {
if (number > 255)
return false;
number = 0;
++countOfDot;
} else if (address[i] < '0' || address[i] > '9') {
return false;
} else {
number *= 10;
number += address[i] - '0';
}
}
return countOfDot == 3;
}
int main() {
int n;
cin >> n;
string address;
while (n--) {
cin >> address;
if (isIPV4Address(address))
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
}
大师们的代码
参考:inet_aton源码
/*
* inet_aton.c,v 1.3 1993/05/19 03:39:32 jch Exp
*/
/* Gated Release 3.5 */
/* Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University. All */
/* rights reserved. Refer to Particulars and other Copyright notices at */
/* the end of this file. */
/* */
#include <sys/types.h>
#include <netinet/in.h>
/*
* Check whether "cp" is a valid ascii representation
* of an Internet address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
* This replaces inet_addr, the return value from which
* cannot distinguish between failure and a local broadcast address.
*/
int
inet_aton(const char *cp, struct in_addr *ap)
{
int dots = 0;
register u_long acc = 0, addr = 0;
do {
register char cc = *cp;
switch (cc) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
acc = acc * 10 + (cc - '0');
break;
case '.':
if (++dots > 3) {
return 0;
}
/* Fall through */
case '\0':
if (acc > 255) {
return 0;
}
addr = addr << 8 | acc;
acc = 0;
break;
default:
return 0;
}
} while (*cp++) ;
/* Normalize the address */
if (dots < 3) {
addr <<= 8 * (3 - dots) ;
}
/* Store it if requested */
if (ap) {
ap->s_addr = htonl(addr);
}
return 1;
}
/*
* ------------------------------------------------------------------------
*
* GateD, Release 3.5
*
* Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University.
* All rights reserved.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Royalty-free licenses to redistribute GateD Release
* 3 in whole or in part may be obtained by writing to:
*
* GateDaemon Project
* Information Technologies/Network Resources
* 200 CCC
* Cornell University
* Ithaca, NY 14853-2601 USA
*
* GateD is based on Kirton's EGP, UC Berkeley's routing
* daemon (routed), and DCN's HELLO routing Protocol.
* Development of GateD has been supported in part by the
* National Science Foundation.
*
* Please forward bug fixes, enhancements and questions to the
* gated mailing list: gated-people@gated.cornell.edu.
*
* ------------------------------------------------------------------------
*
* Portions of this software may fall under the following
* copyrights:
*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are
* permitted provided that the above copyright notice and
* this paragraph are duplicated in all such forms and that
* any documentation, advertising materials, and other
* materials related to such distribution and use
* acknowledge that the software was developed by the
* University of California, Berkeley. The name of the
* University may not be used to endorse or promote
* products derived from this software without specific
* prior written permission. THIS SOFTWARE IS PROVIDED
* ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
可以看出,代码的效率是比我高的,因为我一开始扫描了一遍来计算长度(完全没必要的。。应用场景没有那么长的字符串),然后其中使用switch来处理,也是各种巧妙,令人惊叹!!!还不失可读性!!!