【算法-LeetCode】468. 验证IP地址(数组方法;Array.every();正则)

468. 验证IP地址 - 力扣(LeetCode)

发布:2021年10月7日17:15:14

问题描述及示例

编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。

如果是有效的 IPv4 地址,返回 “IPv4” ;
如果是有效的 IPv6 地址,返回 “IPv6” ;
如果不是上述类型的 IP 地址,返回 “Neither” 。
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:
输入:IP = “172.16.254.1”
输出:“IPv4”
解释:有效的 IPv4 地址,返回 “IPv4”

示例 2:
输入:IP = “2001:0db8:85a3:0:0:8A2E:0370:7334”
输出:“IPv6”
解释:有效的 IPv6 地址,返回 “IPv6”

示例 3:
输入:IP = “256.256.256.256”
输出:“Neither”
解释:既不是 IPv4 地址,又不是 IPv6 地址

示例 4:
输入:IP = “2001:0db8:85a3:0:0:8A2E:0370:7334:”
输出:“Neither”

示例 5:
输入:IP = “1e1.4.5.6”
输出:“Neither”

提示:
IP 仅由英文字母,数字,字符 ‘.’ 和 ‘:’ 组成。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-ip-address
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的题解(Array.every())

总体分为三大步:

  1. 先将 IP. 或者 : 为分隔符分割,获取 IP 的每一个分段 seg 并存于 IPArr 数组中。
  2. 再利用 every() 函数以及自定义的验证函数(isValidIPv4Segment()isValidIPv6Segment())验证 IPArr 中的每个分段是否都为有效的 IP 分段。
  3. 如果 IPArr 中的每个分段都为有效的 IP 分段且分段数量合理,则返回对应的 IP 类型,否则返回 'Neither'

其中最关键的就是第二步和第三步,需要考虑各种有效情况和无效情况,我就是在这里连续遭受了三次毒打:

在这里插入图片描述

第一次毒打:没有考虑IP分段的数量

在这里插入图片描述

第二次毒打:还是没有考虑周全IP分段的数量

在这里插入图片描述

第三次毒打:没有考虑周全IPv6分段的有效性检验

经过这三次毒打,终于算是通过了提交。相关详解请看下方注释:

/**
 * @param {string} IP
 * @return {string}
 */
var validIPAddress = function(IP) {
  // 如果 IP 中同时存在 . 和 : ,那么一定是无效的 IP 地址,所以直接返回 'Neither'
  if(IP.includes('.') && IP.includes(':')) {
    return 'Neither';
  }
  // IPArr用于接收分割出来的 IP 分段
  let IPArr = null;
  //  如果 IP 中有 . ,那么就按 IPv4 的有效性判断标准来判断其有效性
  if(IP.includes('.')) {
    IPArr = IP.split('.');
    // 注意如果是 IPv4,则其分段数量一定是4
    return IPArr.length === 4 && IPArr.every(
      cur => isValidIPv4Segment(cur)
    ) ? 'IPv4' : 'Neither';
  }
  // 如果 IP 中有 : ,那么就按 IPv6 的有效性判断标准来判断其有效性
  IPArr = IP.split(':');
  // 注意如果是 IPv6,则其分段数量一定是8
  return IPArr.length === 8 && IPArr.every(
    cur => isValidIPv6Segment(cur)
  ) ? 'IPv6' : 'Neither';

  // isValidIPv4Segment 用于判断一个字符串是否为有效的 IPv4 分段
  function isValidIPv4Segment(seg) {
    if(/[a-zA-Z]/.test(seg) || seg.length === 0 || (seg.length > 1 && seg[0] === '0')) {
      return false;
    }
    return 0 <= Number(seg) && Number(seg) <= 255;
  }
  // isValidIPv6Segment 用于判断一个字符串是否为有效的 IPv6 分段
  function isValidIPv6Segment(seg) {
    if(/[g-zG-Z]/.test(seg) || seg.length === 0 || seg.length > 4 ) {
      return false;
    }
    return 0 <= parseInt(seg, 16) && parseInt(seg, 16) <= 65535;
  }
};


提交记录
73 / 73 个通过测试用例
状态:通过
执行用时:68 ms, 在所有 JavaScript 提交中击败了65.40%的用户
内存消耗:37.7 MB, 在所有 JavaScript 提交中击败了66.35%的用户
时间:2021/10/07 17:21

上面用到了数组对象的 every() 方法,具体可以参考下方MDN文档:

参考:Array.prototype.every() - JavaScript | MDN

还有一点要注意,那就是 Number() 函数对字符串的转化。当 IP = "1e1.4.5.6" 时,第一个分段为 1e1。如果用 Number() 函数对其进行转换的话,不会出现预期中的 NaN ,而是 10

在这里插入图片描述

Number() 函数对 '1e1' 的转换效果

Number 函数将字符串转为数值,要比 parseInt 函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为 NaN

parseInt('42 cats') // 42
Number('42 cats') // NaN

但是可惜的是,碰上 '1e1' 时,结果好像和我想的不太一样,我目前还没搞清楚原因。

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

更新:2021年10月7日17:18:47

参考:验证 IP 地址 - 验证IP地址 - 力扣(LeetCode)

【更新结束】

有关参考

更新:2021年10月7日17:18:04
参考:Array.prototype.every() - JavaScript | MDN
参考:Number - JavaScript | MDN
参考:javascript 十六进制数字和字符串相互转换_鸟哥的博客-CSDN博客
参考:数据类型的转换 - JavaScript 教程 - 网道
参考:判断一个字符串是否是16进制_yuyeqianhen的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值