跳到主要内容

HJ90. 合法IP

题目描述​

判断输入的字符串是否为合法的 IPv4 地址。

合法的 IPv4 由 4 段组成,每段为 0~255 的十进制整数,段之间用 . 分隔。

输入格式​

一行字符串,形如 192.168.1.1。

输出格式​

合法输出 YES,否则输出 NO。

示例​

示例 1​

输入:

10.137.9.5

输出:

YES

示例 2​

输入:

256.1.1.1

输出:

NO

解题思路​

第一步:理解问题本质​

IPv4 校验 = 恰好 4 段 + 每段是 0~255 的十进制整数。逐个条件检查,任何一个不满足即非法。

第二步:暴力解法​

用正则做严格校验,表达式复杂且难以覆盖所有边界(空段、前导零、非数字等),容易漏判。

第三步:最优解法(逐条件模拟)​

按顺序检查:

  1. split('.') 后必须恰好 4 段
  2. 每段必须 isdigit()(纯数字且非空)
  3. 每段数值必须 0 <= int <= 255
parts = ip.split('.')
if len(parts) != 4:
return False
for part in parts:
if not part.isdigit() or (len(part) > 1 and part[0] == '0'):
return False
if not (0 <= int(part) <= 255):
return False
return True

完整代码实现​

算法可视化 · 逐帧回放这道题的代码7 帧 · 录制输入
import sys


def is_valid_ip(ip: str) -> bool:
parts = ip.split('.')
if len(parts) != 4:
return False
for part in parts:
if not part.isdigit():
return False
if len(part) > 1 and part[0] == '0': # 前导零非法
return False
if not (0 <= int(part) <= 255):
return False
return True


def solve():
ip = sys.stdin.readline().strip()
print("YES" if is_valid_ip(ip) else "NO")


if __name__ == "__main__":
solve()

示例推演​

以 256.1.1.1 为例:

  • 分割 → ['256','1','1','1'],恰好 4 段 ✓
  • 段 256:是数字,但 256 > 255 ✗

结果:NO。


复杂度分析​

解法时间复杂度空间复杂度说明
正则校验O(n)O(1)表达式复杂难维护
逐条件模拟O(n)O(n)清晰直观

n 为 IP 字符串长度


易错点总结​

1. 段数必须恰好 4​

1.2.3(3 段)或 1.2.3.4.5(5 段)都非法,必须先检查段数。

2. 每段必须纯数字​

a.b.c.d 这类含字母的非法,用 isdigit() 检查。

3. 空段处理​

1..2.3 中空段 .split('.') 会产生空字符串,空串 isdigit() 为 False,正确判非法。

4. 前导零​

每段不能有前导零(除非整段就是 0)。如 01.2.3.8 的 01、1.2.3.04 的 04 都非法。需额外判断 len(part) > 1 and part[0] == '0'。

5. 数值范围​

每段必须 0 <= x <= 255,256 超界非法。


扩展思考​

  • 更严格的 IP 校验还会排除前导零(如 01.2.3.4 非法),本题即采用该规则。不同平台规则略有差异,实现前需确认。
  • 可推广到校验 IPv6 或子网掩码。

相关题目​

自测​

加载评论中...