python3解决LeeCode中等题编号468. 验证IP地址
这是一篇解析编程练习网站LeeCode上面的一道题的文章。 题目地址:力扣 分为几步:
- 题目内容
- 官方示例
- 思路解析和 解题方法
题目内容
- 验证IP地址
编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。
IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1; 同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。
然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。
同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。
说明: 你可以认为给定的字符串里没有空格或者其他特殊字符。
官方示例
示例1
输入: “172.16.254.1”
输出: “IPv4”
解释: 这是一个有效的 IPv4 地址, 所以返回 “IPv4”。
示例2
输入: “2001:0db8:85a3:0:0:8A2E:0370:7334”
输出: “IPv6”
解释: 这是一个有效的 IPv6 地址, 所以返回 “IPv6”。
示例3
输入: “256.256.256.256”
输出: “Neither”
解释: 这个地址既不是 IPv4 也不是 IPv6 地址。
思路解析和 解题方法
最直接的方法是直接调用Python 中的跟ip地址相关的包:ipaddress 它是专门用来处理ipv4和ipv6相关的包,像这种/24生成子网ip地址之类的非常方便。而题目要求就是判断是不是有效的ipv4或者ipv6,那么ipaddress.ip_address就可以很方便地解决这个问题了。请看官方说明
'''
ipaddress.ip_address(address)
Return an IPv4Address or IPv6Address object depending on the IP address passed as argument. Either IPv4 or IPv6 addresses may be supplied; integers less than 2**32 will be considered to be IPv4 by default. A ValueError is raised if address does not represent a valid IPv4 or IPv6 address.
简单讲就是:
通过一个ip地址将会返回一个ipv4或者ipv6的对象,如果不是有效地址将会生成一个valueerror。
>>>
ipaddress.ip_address('192.168.0.1')
IPv4Address('192.168.0.1')
ipaddress.ip_address('2001:db8::')
IPv6Address('2001:db8::')
'''
那么判断代码也就清楚了
import ipaddress
class Solution:
def validIPAddress(self, IP: str) -> str:
try:
addtype = type(IP)
if addtype == ipaddress.IPv4Address:
return "IPv4"
return "IPv6"
except ValueError:
return "Neither"
但是在实际运行中提交发生错误,这是由于"01.01.01.01"的地址被认为是合法的ipv4,而在题目中却规定不能有0
“IPv4 地址内的数不会以 0 开头”
因此我们应该首先把ip地址分段在组合成新的数组,最后交给ipaddress包处理就可以了。
且看代码:
import ipaddress
class Solution:
def validIPAddress(self, IP: str) -> str:
try:
addtype = type(ipaddress.ip_address(IP))
if addtype == ipaddress.IPv4Address:
for little in IP.split("."):
if len(little)>1 and "0" == little[0]:
return "Neither"
return "IPv4"
IP = IP.split(":")
for little in IP:
if len(little)>4 or little=='':
return "Neither"
return "IPv6"
except ValueError:
return "Neither"
经过n次调试后,上述代码终于可以通过了。。。
运行时间40ms,内存消耗13.9MB
总结
实际情况本来是ipaddress包就可以解决的,但是在题目中引入了很多的限制条件,无形中增加了很多的麻烦,不过只需要根据提交测试的错误结果一步步改正就可以了。 另外大家也可以好好学习下ipaddress包,在处理网络地址方面的问题上真的很方便的。
- 原文作者:春江暮客
- 原文链接:https://www.bobobk.com/671.html
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。